Utiliser des listes de données sur les plates-formes Apple

Obtenir un FIRDatabaseReference

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

Swift

Remarque:Ce produit Firebase n'est pas disponible sur la cible de l'extrait d'application.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

Remarque:Ce produit Firebase n'est pas disponible sur la cible de l'extrait d'application.
@property (strong, nonatomic) FIRDatabaseReference *ref;

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

Lire et écrire des listes

Ajouter à une liste de données

Utilisez la méthode childByAutoId pour ajouter des données à une liste dans des 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 conflit d'écriture. La clé unique générée par childByAutoId est basée sur un code temporel. Les éléments de la liste sont donc automatiquement trié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 de l'enfant ou définir des données pour celui-ci. 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 en savoir plus, consultez l'exemple de distribution ramifiée des données.

Écouter les événements enfants

Les événements enfants sont déclenchés en réponse à des opérations spécifiques qui affectent les enfants d'un nœud à partir d'une opération, comme l'ajout d'un enfant via la méthode childByAutoId ou la mise à jour d'un enfant via la méthode updateChildValues.

Type d'événement Utilisation habituelle
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 à chaque fois qu'un nouvel enfant est ajouté au chemin d'accès spécifié. L'écouteur reçoit un instantané contenant les données du nouvel enfant.
FIRDataEventTypeChildChanged É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 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 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é.
FIRDataEventTypeChildMoved Écoutez les modifications apportées à l'ordre des éléments d'une liste ordonnée. Cet événement est déclenché chaque fois qu'une mise à jour entraîne le réordonnancement 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 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 :

Swift

Remarque:Ce produit Firebase n'est pas disponible sur la cible de l'extrait d'application.
// 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
  )
})

Objective-C

Remarque:Ce produit Firebase n'est pas disponible sur la cible de l'extrait d'application.
// 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];
 }];

É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 observateur FIRDataEventTypeValue à une liste de données, la liste complète des données sera renvoyée sous la forme d'un seul DataSnapshot, 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é reste une liste, mais ne contient qu'un seul élément. Pour accéder à l'élément, vous devez effectuer une boucle sur le résultat :

Swift

Remarque:Ce produit Firebase n'est pas disponible sur la cible de l'extrait d'application.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-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 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 FIRDatabaseQuery Realtime Database pour récupérer des données triées par clé, 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
queryOrderedByKey Classez les résultats par clés enfants.
queryOrderedByValue Classez 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 méthode de tri à la fois. Appeler une méthode de tri plusieurs fois dans la même requête génère une erreur.

L'exemple suivant montre comment récupérer la liste des posts les plus populaires d'un utilisateur, triés en fonction de leur nombre d'étoiles:

Swift

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

Objective-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 posts de l'utilisateur à partir du chemin d'accès dans la base de données en fonction de son ID utilisateur, triés par nombre d'étoiles reçues par chaque post. Cette technique d'utilisation d'ID en tant que clés d'index est appelée "distribution ramifiée des données". Pour en savoir plus à son sujet, consultez la page Structurer votre base de données.

L'appel de la méthode queryOrderedByChild spécifie la clé enfant à utiliser pour trier les résultats. Dans cet exemple, les posts sont triés en fonction de la valeur de l'élément enfant "starCount" de chaque post. Les requêtes peuvent également être triées par enfants imbriqués, si vos données se présentent 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 classer les éléments de notre liste en fonction de valeurs imbriquées sous la clé metrics en spécifiant le chemin relatif à l'enfant imbriqué dans notre appel queryOrderedByChild.

Swift

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

Objective-C

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

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

Filtrer les données

Pour filtrer les données, vous pouvez combiner l'une des méthodes de limite ou de plage avec une méthode de tri lors de la création d'une requête.

Méthode Utilisation
queryLimitedToFirst Définit le nombre maximal d'éléments à renvoyer à partir du début de la liste numérotée des résultats.
queryLimitedToLast Définit le nombre maximal d'éléments à renvoyer à partir de la fin de la liste de résultats triée.
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 Les articles sont 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 maximal 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, de sorte que le nombre total reste à 100.

L'exemple suivant montre comment une application de bloggage peut récupérer la liste des 100 posts les plus récents de tous les utilisateurs:

Swift

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

Objective-C

Remarque:Ce produit Firebase n'est pas disponible sur la cible de l'extrait d'application.
// 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épart, 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 ayant une valeur spécifique.

Ordre des données de requête

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, 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 dont la clé est une valeur de chaîne viennent ensuite, triés par ordre lexicographique croissant.

queryOrderedByValue

Lorsque vous utilisez queryOrderedByValue, les enfants sont triés en fonction de leur valeur. Les critères de tri 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

Lorsque vous utilisez queryOrderedByChild, 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 nil 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 une valeur de false, ils sont triés de manière lexicographique par clé.
  3. Les enfants dont la valeur est true pour la clé enfant spécifiée sont les suivants. Si plusieurs enfants ont une valeur de true, ils sont triés par clé de façon lexicographique.
  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 sont placés en dernier et sont triés par ordre croissant, de manière lexicographique, en fonction de la clé.

Dissocier les écouteurs

Les observateurs ne cessent pas automatiquement de synchroniser les 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 conserve tous les objets capturés lors de la fermeture du gestionnaire d'événements, ce qui peut entraîner des fuites de mémoire. Lorsqu'un observateur n'est plus nécessaire, supprimez-le en transmettant le FIRDatabaseHandle associé à la méthode removeObserverWithHandle.

Lorsque vous ajoutez un bloc de rappel à une référence, un FIRDatabaseHandle est renvoyé. Ces poignées peuvent être utilisées 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 généré. Pour arrêter la synchronisation des données à cet emplacement, vous devez supprimer tous les observateurs à un emplacement en appelant la méthode removeAllObservers.

Appeler removeObserverWithHandle ou removeAllObservers sur un écouteur ne supprime pas automatiquement les écouteurs enregistrés sur ses nœuds enfants. Vous devez également suivre ces références ou poignées pour les supprimer.

Étapes suivantes