Travailler avec des listes de données sur les plateformes Apple

Obtenir une référence FIRDatabaseReference

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

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
var ref: DatabaseReference!

ref = Database.database().reference()

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

Listes de lecture et d'écriture

Ajouter à une liste de données

Utilisez la méthode childByAutoId pour ajouter des données à une liste dans les applications multi-utilisateurs. La méthode childByAutoId 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 conflits d'écriture. La clé unique générée par childByAutoId est basée sur un horodatage, de sorte que les éléments de la liste sont automatiquement classés par ordre chronologique.

Vous pouvez utiliser la référence aux nouvelles données renvoyées par la méthode childByAutoId pour obtenir la valeur de la clé générée automatiquement par l'enfant ou définir les données pour l'enfant. L’appel de getKey sur une référence childByAutoId renvoie 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 plus d’informations, consultez l’ exemple de répartition des données .

Écoutez les événements pour enfants

Les événements enfants sont déclenchés en réponse à des opérations spécifiques qui se produisent sur les enfants d'un nœud à partir d'une opération telle qu'un nouvel enfant ajouté via la méthode childByAutoId ou un enfant mis à jour via la méthode updateChildValues .

Type d'événement Utilisation typique
FIRDataEventTypeChildAdded 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 à nouveau chaque fois qu'un nouvel enfant est ajouté au chemin spécifié. L'auditeur reçoit un instantané contenant les données du nouvel enfant.
FIRDataEventTypeChildChanged Écoutez 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 toutes les modifications apportées aux descendants du nœud enfant. L'instantané transmis à l'écouteur d'événements contient les données mises à jour pour l'enfant.
FIRDataEventTypeChildRemoved Écoutez les éléments supprimés d’une liste. Cet événement est déclenché lorsqu'un enfant immédiat est supprimé. L'instantané transmis au bloc de rappel contient les données de l'enfant supprimé.
FIRDataEventTypeChildMoved Écoutez les changements dans l’ordre des éléments dans une liste ordonnée. Cet événement est déclenché chaque fois qu'une mise à jour entraîne une réorganisation de l'enfant. Il est utilisé avec des données triées par queryOrderedByChild ou queryOrderedByValue .

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 blog social peut utiliser ces méthodes ensemble pour surveiller l'activité dans les commentaires d'une publication, comme indiqué ci-dessous :

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(
    at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(
    at: [IndexPath(row: index, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

Écoutez 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 s'avère utile.

Attacher un observateur FIRDataEventTypeValue à une liste de données renverra la liste complète des données sous la forme d'un seul DataSnapshot, sur lequel vous pourrez ensuite boucler pour accéder à des enfants individuels.

Même lorsqu'il n'existe qu'une seule correspondance pour la requête, l'instantané reste une liste ; il ne contient qu’un seul élément. Pour accéder à l'élément, vous devez parcourir le résultat :

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

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

Trier et filtrer les données

Vous pouvez utiliser la classe Realtime Database FIRDatabaseQuery pour récupérer des données triées par clé, par valeur ou par la valeur d'un enfant. Vous pouvez également filtrer le résultat trié sur un nombre spécifique de résultats ou 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 order-by pour déterminer comment les résultats sont classés :

Méthode Usage
queryOrderedByKey Trier les résultats par clés enfants.
queryOrderedByValue Triez les résultats par valeurs enfants.
queryOrderedByChild Triez les résultats en fonction de la valeur d’une clé enfant spécifiée ou d’un chemin enfant imbriqué.

Vous ne pouvez utiliser qu’une seule méthode de tri à la fois. L’appel d’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 une liste des meilleures publications d'un utilisateur triées par nombre d'étoiles :

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

Cette requête récupère les publications de l'utilisateur à partir du chemin dans la base de données en fonction de son identifiant utilisateur, classées par nombre d'étoiles reçues par chaque publication. Cette technique d'utilisation des identifiants comme clés d'index est appelée répartition des données. Vous pouvez en savoir plus à ce sujet dans Structurez votre base de données .

L’appel à la méthode queryOrderedByChild spécifie la clé enfant selon laquelle trier les résultats. Dans cet exemple, les publications sont triées selon la valeur de l'enfant "starCount" dans chaque publication. Les requêtes peuvent également être classées par enfants imbriqués, au cas où vous disposez de données ressemblant à ceci :

"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 les éléments de notre liste par valeurs imbriquées sous la clé de metrics en spécifiant le chemin relatif vers l'enfant imbriqué dans notre appel queryOrderedByChild .

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

Pour plus d'informations sur la façon dont les autres types de données sont ordonnés, consultez Comment les données de requête sont ordonnées .

Filtrage des données

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

Méthode Usage
queryLimitedToFirst Définit le nombre maximum d'éléments à renvoyer à partir du début de la liste ordonnée des résultats.
queryLimitedToLast Définit le nombre maximum d'éléments à renvoyer à partir de la fin de la liste ordonnée des résultats.
queryStartingAtValue 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.
queryStartingAfterValue Renvoie les éléments supérieurs à la clé ou à la valeur spécifiée, en fonction de la méthode de tri choisie.
queryEndingAtValue Renvoie les éléments inférieurs ou égaux à la clé ou à la valeur spécifiée, en fonction de la méthode de tri choisie.
queryEndingBeforeValue Renvoie les éléments inférieurs à la clé ou à la valeur spécifiée, en fonction de la méthode de tri choisie.
queryEqualToValue 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 queryStartingAtValue et queryEndingAtValue pour limiter les résultats à une plage de valeurs spécifiée.

Limiter le nombre de résultats

Vous pouvez utiliser les méthodes queryLimitedToFirst et queryLimitedToLast pour définir un nombre maximum d'enfants à synchroniser pour un rappel donné. Par exemple, si vous utilisez queryLimitedToFirst pour définir une limite de 100, vous ne recevez initialement que 100 rappels FIRDataEventTypeChildAdded . Si vous avez moins de 100 éléments stockés dans votre base de données Firebase, un rappel FIRDataEventTypeChildAdded se déclenche pour chaque élément.

À mesure que les éléments changent, vous recevez des rappels FIRDataEventTypeChildAdded pour les éléments qui entrent dans la requête et des rappels FIRDataEventTypeChildRemoved pour les éléments qui en sortent afin que le nombre total reste à 100.

L'exemple suivant montre comment un exemple d'application de blog peut récupérer une liste des 100 publications les plus récentes de tous les utilisateurs :

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur la cible App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

Filtrer par clé ou valeur

Vous pouvez utiliser queryStartingAtValue , queryStartingAfterValue , queryEndingAtValue , queryEndingBeforeValue et queryEqualToValue pour choisir des points de début, de fin et d'équivalence arbitraires pour les requêtes. Cela peut être utile pour paginer des données ou rechercher des éléments avec des enfants qui ont une valeur spécifique.

Comment les données de requête sont ordonnées

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

queryOrderedByKey

Lorsque vous utilisez queryOrderedByKey pour trier vos données, les données sont renvoyées par ordre croissant par clé.

  1. Les enfants possédant une clé pouvant être analysée comme un entier de 32 bits viennent en premier, triés par ordre croissant.
  2. Les enfants avec une valeur de chaîne comme clé viennent ensuite, triés lexicographiquement par ordre croissant.

queryOrderedByValue

Lors de l'utilisation queryOrderedByValue , les enfants sont classés selon leur valeur. Les critères de classement sont les mêmes que dans queryOrderedByChild , sauf que la valeur du nœud est utilisée à la place de la valeur d'une clé enfant spécifiée.

queryOrderedByChild

Lors de l'utilisation queryOrderedByChild , les données contenant la clé enfant spécifiée sont classées comme suit :

  1. Les enfants avec une valeur nil pour la clé enfant spécifiée viennent en premier.
  2. Les enfants avec une valeur false pour la clé enfant spécifiée viennent ensuite. Si plusieurs enfants ont la valeur false , ils sont triés lexicographiquement par clé.
  3. Les enfants avec une valeur true pour la clé enfant spécifiée viennent ensuite. Si plusieurs enfants ont la valeur true , ils sont triés lexicographiquement par clé.
  4. Les enfants ayant une valeur numérique viennent 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 lexicographiquement par ordre croissant. Si plusieurs enfants ont la même valeur pour le nœud enfant spécifié, ils sont classés lexicographiquement par clé.
  6. Les objets viennent en dernier et sont triés lexicographiquement par clé par ordre croissant.

Détacher les auditeurs

Les observateurs n'arrêtent pas automatiquement la synchronisation des données lorsque vous quittez un ViewController . Si un observateur n'est pas correctement supprimé, il continue de synchroniser les données avec la mémoire locale et conservera tous les objets capturés lors de la fermeture du gestionnaire d'événements, ce qui peut provoquer des fuites de mémoire. Lorsqu'un observateur n'est plus nécessaire, supprimez-le en passant le FIRDatabaseHandle associé à la méthode removeObserverWithHandle .

Lorsque vous ajoutez un bloc de rappel à une référence, un FIRDatabaseHandle est renvoyé. Ces handles peuvent être utilisés pour supprimer le bloc de rappel.

Si plusieurs écouteurs ont été ajoutés à une référence de base de données, chaque écouteur est appelé lorsqu'un événement est déclenché. Afin d'arrêter la synchronisation des données à cet emplacement, vous devez supprimer tous les observateurs d'un emplacement en appelant la méthode removeAllObservers .

L’appel de removeObserverWithHandle ou removeAllObservers sur un écouteur ne supprime pas automatiquement les écouteurs enregistrés sur ses nœuds enfants ; vous devez également garder une trace de ces références ou poignées pour les supprimer.

Prochaines étapes