Utiliser des listes de données

Obtenir une référence de base de données

Pour lire ou écrire des données à partir de la base de données, vous avez besoin d'une instance de DatabaseReference :

DatabaseReference ref = FirebaseDatabase.instance.ref();

Lire et écrire des listes

Ajouter à une liste de données

Utilisez la méthode push() pour ajouter des données à une liste dans les applications multi-utilisateurs. La méthode push() génère une clé unique chaque fois qu'un nouvel enfant est ajouté à la référence Firebase spécifiée. En utilisant ces clés générées automatiquement pour chaque nouvel élément de la liste, plusieurs clients peuvent ajouter des enfants au même emplacement en même temps sans conflit d'écriture. La clé unique générée par push() est basé sur un code temporel. Les éléments de la liste sont donc automatiquement classés chronologiquement.

Vous pouvez utiliser la référence aux nouvelles données renvoyées par la méthode push() pour obtenir la valeur de la clé générée automatiquement ou définir des données pour l'enfant. La La propriété .key d'une référence push() contient la clé générée automatiquement.

Vous pouvez utiliser ces clés générées automatiquement pour simplifier l'aplatissement de votre structure de données. Pour en savoir plus, consultez l'exemple de distribution ramifiée des données.

Par exemple, vous pouvez utiliser push() pour ajouter un article à une liste de posts. dans une application de réseau social:

DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
  // ...
});

Écouter les événements enfants

Les événements enfants sont déclenchés en réponse à des opérations spécifiques qui se produisent les enfants d'un nœud à partir d'une opération, par exemple un nouvel enfant ajouté via le push() ou un enfant mis à jour via la méthode update().

Événement Utilisation habituelle
onChildAdded Récupérez des listes d'éléments ou écoutez les ajouts à une liste d'éléments. Cet événement est déclenché une fois pour chaque enfant existant, puis à chaque fois qu'un nouvel enfant est ajouté au chemin d'accès spécifié. Un instantané contenant les données du nouvel enfant est transmis à l'écouteur.
onChildChanged Écouter les modifications apportées aux éléments d'une liste Cet événement est déclenché chaque fois qu'un nœud enfant est modifié. Cela inclut toute modification apportée aux descendants du nœud enfant. L'instantané a réussi à l'écouteur d'événements contient les données mises à jour pour l'enfant.
onChildRemoved Écoutez les éléments supprimés d'une liste. Cet événement se déclenche lorsqu'un enfant immédiat est supprimé. L'instantané transmis au bloc de rappel contient les données de l'enfant supprimé.
onChildMoved Écoutez les modifications apportées à l'ordre des éléments dans une liste numérotée. Les événements onChildMoved suivent toujours l'événement onChildChanged qui a entraîné la modification de l'ordre de l'élément (en fonction de votre méthode de tri actuelle).

Chacun de ces éléments peut être utile pour écouter les modifications apportées à un nœud spécifique dans une base de données. Par exemple, une application de bloggage sur les réseaux sociaux peut utiliser ces méthodes ensemble pour surveiller l'activité dans les commentaires d'un post, comme indiqué ci-dessous :

final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
  // A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
  // A comment has changed; use the key to determine if we are displaying this
  // comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
  // A comment has been removed; use the key to determine if we are displaying
  // this comment and if so remove it.
});

Écouter les événements de valeur

Bien que l'écoute des événements enfants soit la méthode recommandée pour lire des listes de données, il existe des situations où l'écoute des événements de valeur sur une référence de liste est utile.

Si vous associez un écouteur value à une liste de données, la liste complète des données sera renvoyée sous la forme d'un seul instantané, que vous pourrez ensuite parcourir en boucle pour accéder à des enfants individuels.

Même s'il n'y a qu'une seule correspondance pour la requête, l'instantané est toujours list elle ne contient qu'un seul élément. Pour accéder à l'élément, vous devez effectuer une boucle sur le résultat :

myTopPostsQuery.onValue.listen((event) {
  for (final child in event.snapshot.children) {
    // Handle the post.
  }
}, onError: (error) {
  // Error.
});

Ce modèle peut s'avérer utile lorsque vous souhaitez récupérer tous les enfants d'une liste en une seule opération, plutôt que d'écouter des événements d'ajout d'enfants supplémentaires.

Trier et filtrer des données

Vous pouvez utiliser la classe Query pour récupérer des données triées par par valeur ou par valeur d'un enfant. Vous pouvez également filtrer les résultats triés en fonction d'un nombre spécifique de résultats, d'une plage de clés ou de valeurs.

Trier les données

Pour récupérer des données triées, commencez par spécifier l'une des méthodes de tri pour déterminer l'ordre des résultats :

Méthode Utilisation
orderByChild() Triez les résultats en fonction de la valeur d'une clé enfant ou d'un chemin enfant imbriqué spécifié.
orderByKey() Classez les résultats par clés enfants.
orderByValue() Triez les résultats par valeurs enfants.

Vous ne pouvez utiliser qu'une seule méthode de tri à la fois. Appeler une méthode "order-by" plusieurs fois dans la même requête génère une erreur.

L'exemple suivant montre comment récupérer la liste des meilleurs posts d'un utilisateur, triés par nombre d'étoiles :

final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
    .ref("user-posts/$myUserId")
    .orderByChild("starCount");

Ce code définit une requête qui, lorsqu'elle est combinée à un écouteur enfant, synchronise le client avec les messages de l'utilisateur à partir du chemin d'accès dans la base de données. en fonction de leur ID utilisateur, classés selon le nombre d'étoiles que chaque post a reçues. Cette technique d'utilisation des ID comme clés d'index s'appelle "fan-out" des données. Pour en savoir plus, consultez Structurer votre base de données.

L'appel de la méthode orderByChild() spécifie la clé enfant à utiliser pour trier les résultats. Dans ce cas, les messages sont triés en fonction de la valeur de leur "starCount" enfant respectif. Les requêtes peuvent également être triées par ordre enfants, au cas où vos données se présenteraient comme suit:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

Dans ce cas, nous pouvons trier nos éléments de liste par valeurs imbriquées sous la clé metrics en spécifiant le chemin relatif vers l'enfant imbriqué dans notre appel orderByChild().

final mostViewedPosts =
    FirebaseDatabase.instance.ref('posts').orderByChild('metrics/views');

Pour en savoir plus sur l'ordre des autres types de données, consultez la section Ordre des données de requête.

Filtrer les données

Pour filtrer les données, vous pouvez combiner n'importe quelle méthode de limite ou de plage avec une méthode ordre par lors de la création d'une requête.

Méthode Utilisation
limitToFirst() Définit le nombre maximal d'éléments à renvoyer à partir du début de la variable une liste numérotée de résultats.
limitToLast() Définit le nombre maximal d'éléments à renvoyer à partir de la fin de la liste de résultats triée.
startAt() Renvoie les éléments supérieurs ou égaux à la clé ou à la valeur spécifiée, en fonction de la méthode de tri choisie.
startAfter() Afficher des éléments supérieurs à la clé ou à la valeur spécifiée en fonction de la méthode de tri choisie.
endAt() Affiche des éléments inférieurs ou égaux à la clé ou à la valeur spécifiée. en fonction de la méthode de tri choisie.
endBefore() Afficher des éléments inférieurs à la clé ou à la valeur spécifiée en fonction de la méthode de tri choisie.
equalTo() Renvoie les éléments égaux à la clé ou à la valeur spécifiée, en fonction de la méthode de tri choisie.

Contrairement aux méthodes de tri, vous pouvez combiner plusieurs fonctions de limite ou de plage. Par exemple, vous pouvez combiner les méthodes startAt() et endAt() pour limiter les résultats à une plage de valeurs spécifiée.

Limiter le nombre de résultats

Vous pouvez utiliser les méthodes limitToFirst() et limitToLast() pour définir un Nombre maximal d'enfants à synchroniser pour un événement donné. Par exemple, si vous utilisez limitToFirst() pour définir une limite de 100, vous ne recevez initialement que 100 événements onChildAdded. Si vous stockez moins de 100 éléments dans votre base de données Firebase, un événement onChildAdded se déclenche pour chaque élément.

À mesure que les éléments changent, vous recevez onChildAdded événements pour les éléments qui entrent dans le champ une requête et des événements onChildRemoved pour les éléments qui s'en abandonnent le nombre total reste à 100.

L'exemple suivant montre comment une application de blog définit une requête pour récupérer la liste des 100 posts les plus récents de tous les utilisateurs:

final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);

Cet exemple ne définit qu'une requête. Pour synchroniser réellement les données, il doit disposer d'un écouteur associé.

Filtrer par clé ou valeur

Vous pouvez utiliser startAt(), startAfter(), endAt(), endBefore() et equalTo() pour choisir des points de début, de fin et d'équivalence arbitraires pour requêtes. Cela peut être utile pour la pagination des données ou la recherche d'éléments avec enfants qui ont une valeur spécifique.

Comment les données de requête sont-elles ordonnées ?

Cette section explique comment les données sont triées par chacune des méthodes de tri de la classe Query.

orderByChild

Lorsque vous utilisez orderByChild(), les données contenant la clé enfant spécifiée sont triées comme suit :

  1. Les enfants dont la valeur de la clé enfant spécifiée est null sont affichés en premier.
  2. Les enfants dont la valeur est false pour la clé enfant spécifiée viennent ensuite. Si plusieurs enfants ont la valeur false, ils sont triées de manière lexicographique par clé.
  3. Enfants dont la valeur est true pour la clé enfant spécifiée viennent ensuite. Si plusieurs enfants ont la valeur true, ils sont triées de manière lexicographique par clé.
  4. Les enfants avec une valeur numérique arrivent ensuite, triés par ordre croissant. Si plusieurs enfants ont la même valeur numérique pour le nœud enfant spécifié, ils sont triés par clé.
  5. Les chaînes viennent après les nombres et sont triées par ordre lexicographique croissant. Si plusieurs enfants ont la même valeur pour le nœud enfant spécifié, ils sont triés par clé de manière lexicographique.
  6. Les objets apparaissent en dernier et sont triés de façon lexicographique par clé, dans l'ordre croissant.

orderByKey

Lorsque vous utilisez orderByKey() pour trier vos données, elles sont renvoyées par ordre croissant par clé.

  1. Les enfants dont la clé peut être analysée en tant qu'entier 32 bits sont affichés en premier, triés par ordre croissant.
  2. Les enfants avec une valeur de chaîne comme clé arrivent ensuite, triés de manière lexicographique par ordre croissant.

orderByValue

Lorsque vous utilisez orderByValue(), les enfants sont triés en fonction de leur valeur. L'ordre de tri les critères sont les mêmes que dans orderByChild(), à la différence que la valeur du nœud est utilisée à la place de la valeur d'une clé enfant spécifiée.

Dissocier les écouteurs

Les rappels sont supprimés en appelant la méthode off() sur votre Documentation de référence sur la base de données Firebase

Vous pouvez supprimer un seul écouteur en le transmettant en tant que paramètre à off(). Appeler off() sur l'emplacement sans argument supprime tous les écouteurs à cet emplacement l'emplacement.

L'appel de off() sur un écouteur parent ne supprime pas automatiquement les écouteurs enregistrés sur ses nœuds enfants. off() doit également être appelé sur tous les écouteurs enfants pour supprimer le rappel.

Étapes suivantes