Récupérer des données avec Firebase Realtime Database pour C++

Ce document couvre les bases de la récupération de données, ainsi que le tri et le filtrage des données Firebase.

Avant de commencer

Assurez-vous d'avoir configuré votre application et d'avoir accès à la base de données, comme indiqué dans le Get Started guide.

Récupérer des données

Les données Firebase sont récupérées par un appel unique à GetValue() ou en les associant à un ValueListener sur une référence FirebaseDatabase. L'écouteur de valeur est appelé une fois pour l'état initial des données, puis chaque fois que les données changent.

Obtenir une DatabaseReference

Pour écrire des données dans la base de données, vous avez besoin d'une instance de DatabaseReference :

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

Lire les données une seule fois

Vous pouvez utiliser la méthode GetValue() pour lire une seule fois un instantané statique du contenu d'un chemin d'accès donné. Le résultat de la tâche contient un instantané contenant toutes les données à cet emplacement, y compris les données enfants. Si aucune donnée n'est présente, l'instantané renvoyé est null.

  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").GetValue();

La requête a été effectuée, mais nous devons attendre que l'objet Future soit terminé avant de pouvoir lire la valeur. Étant donné que les jeux s'exécutent généralement en boucle et sont moins axés sur les rappels que les autres applications, vous interrogez généralement l'état d'achèvement.

  // In the game loop that polls for the result...

  if (result.status() != firebase::kFutureStatusPending) {
    if (result.status() != firebase::kFutureStatusComplete) {
      LogMessage("ERROR: GetValue() returned an invalid result.");
      // Handle the error...
    } else if (result.error() != firebase::database::kErrorNone) {
      LogMessage("ERROR: GetValue() returned error %d: %s", result.error(),
                 result.error_message());
      // Handle the error...
    } else {
      firebase::database::DataSnapshot snapshot = result.result();
      // Do something with the snapshot...
    }
  }

Cet exemple montre une vérification d'erreur de base. Pour en savoir plus sur la vérification des erreurs et sur les moyens de déterminer quand le résultat est prêt, consultez la référence firebase::Future pour plus d' informations.

Écouter les événements

Vous pouvez ajouter des écouteurs pour vous abonner aux modifications des données :

Classe de base ValueListener

Rappel Utilisation typique
OnValueChanged Lire et écouter les modifications apportées à l'ensemble du contenu d'un chemin d'accès.

Classe de base OnChildListener

OnChildAdded Récupérer des listes d'éléments ou écouter les ajouts à une liste d'éléments. Utilisation suggérée avec OnChildChanged et OnChildRemoved pour surveiller les modifications apportées aux listes.
OnChildChanged Écouter les modifications apportées aux éléments d'une liste. Utiliser avec OnChildAdded et OnChildRemoved pour surveiller les modifications apportées aux listes.
OnChildRemoved Écouter les éléments supprimés d'une liste. Utiliser avec OnChildAdded et OnChildChanged pour surveiller les modifications apportées aux listes.
OnChildMoved Écouter les modifications apportées à l'ordre des éléments dans une liste ordonnée. Les rappels OnChildMoved suivent toujours les OnChildChanged rappels en raison de la modification de l'ordre de l'élément (en fonction de votre méthode de tri actuelle).

Classe ValueListener

Vous pouvez utiliser les rappels OnValueChanged pour vous abonner aux modifications apportées au contenu d'un chemin d'accès donné. Ce rappel est déclenché une fois lorsque l'écouteur est associé, puis chaque fois que les données, y compris les enfants, changent. Le rappel reçoit un instantané contenant toutes les données à cet emplacement, y compris les données enfants. Si aucune donnée n'est présente, l'instantané renvoyé est null.

L'exemple suivant montre un jeu qui récupère les scores d'un classement à partir de la base de données :

  class LeadersValueListener : public firebase::database::ValueListener {
   public:
    void OnValueChanged(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code,
                 error_message);
    }
  };

  // Elsewhere in the code...

  LeadersValueListener* listener = new LeadersValueListener();
  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

Le résultat Future&ltDataSnapshot&gt contient les données à l'emplacement spécifié dans la base de données au moment de l'événement. L'appel de value() sur un instantané renvoie un Variant représentant les données.

Dans cet exemple, la méthode OnCancelled est également remplacée pour vérifier si la lecture est annulée. Par exemple, une lecture peut être annulée si le client n'est pas autorisé à lire à partir d'un emplacement de base de données Firebase. Le database::Error indique la raison de l'échec.

Classe ChildListener

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 PushChild() ou un enfant mis à jour via la méthode UpdateChildren(). 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, un jeu peut utiliser ces méthodes ensemble pour surveiller l'activité dans les commentaires d'une session de jeu, comme illustré ci-dessous :

  class SessionCommentsChildListener : public firebase::database::ChildListener {
   public:
    void OnChildAdded(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildChanged(const firebase::database::DataSnapshot& snapshot,
                        const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildRemoved(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot ...
    }
    void OnChildMoved(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s",
                 error_code, error_message);
    }
  };

  // elsewhere ....

  SessionCommentsChildListener* listener = new SessionCommentsChildListener();
  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

Le rappel OnChildAdded est généralement utilisé pour récupérer une liste d'éléments dans une base de données Firebase. Le rappel OnChildAdded est appelé 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.

Le rappel OnChildChanged est appelé chaque fois qu'un nœud enfant est modifié. Cela inclut toutes les modifications apportées aux descendants du nœud enfant. Il est généralement utilisé conjointement avec les appels OnChildAdded et OnChildRemoved pour répondre aux modifications apportées à une liste d'éléments. L'instantané transmis à l'écouteur contient les données mises à jour de l'enfant.

Le rappel OnChildRemoved est déclenché lorsqu'un enfant immédiat est supprimé. Il est généralement utilisé conjointement avec les rappels OnChildAdded et OnChildChanged. L'instantané transmis au rappel contient les données de l'enfant supprimé.

Le rappel OnChildMoved est déclenché chaque fois que l'appel OnChildChanged est déclenché par une mise à jour qui entraîne le réordonnancement de l'enfant. Il est utilisé avec des données triées avec OrderByChild ou OrderByValue.

Trier et filtrer les données

Vous pouvez utiliser la classe Realtime Database Query pour récupérer des données triées par clé, par valeur ou par 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 de tri pour déterminer l'ordre des résultats :

Méthode Utilisation
OrderByChild() Trier les résultats par la valeur d'une clé enfant spécifiée.
OrderByKey() Trier les résultats par clés enfants.
OrderByValue() Trier les résultats par valeurs enfants.

Vous ne pouvez utiliser qu'une seule méthode de tri à la fois. L'appel d'une méthode de tri plusieurs fois dans la même requête génère une erreur.

L'exemple suivant montre comment vous pouvez vous abonner à un classement de scores trié par score.

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score");

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Cela définit un firebase::Query qui, combiné à un ValueListener, synchronise le client avec le classement dans la base de données, trié par le score de chaque entrée. Pour en savoir plus sur la structuration efficace de vos données, consultez Structurer votre base de données.

L'appel à la méthode OrderByChild() spécifie la clé enfant par laquelle trier les résultats. Dans ce cas, les résultats sont triés par la valeur de la "score" valeur dans chaque enfant. Pour en savoir plus sur le tri des autres types de données, consultez Comment les données de requête sont triées.

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
LimitToFirst() Définit le nombre maximal d'éléments à renvoyer depuis le début de la liste ordonnée des résultats.
LimitToLast() Définit le nombre maximal d'éléments à renvoyer depuis la fin de la liste ordonnée des résultats.
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.
EndAt() 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.
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.

Même s'il n'y a qu'une seule correspondance pour la requête, l'instantané reste une liste. Il ne contient qu'un seul élément.

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 rappel donné. Par exemple, si vous utilisez LimitToFirst() pour définir une limite de 100, vous ne recevez initialement que 100 rappels OnChildAdded au maximum. Si vous avez moins de 100 éléments stockés dans votre base de données Firebase, un rappel OnChildAdded est déclenché pour chaque élément.

Lorsque des éléments changent, vous recevez des rappels OnChildAdded pour les éléments qui entrent dans la requête et des rappels OnChildRemoved pour les éléments qui en sortent, de sorte que le nombre total reste à 100.

Par exemple, le code ci-dessous renvoie le meilleur score d'un classement :

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1);

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Filtrer par clé ou par valeur

Vous pouvez utiliser StartAt(), EndAt() et EqualTo() 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 trouver des éléments avec des enfants ayant une valeur spécifique.

Comment les données de requête sont trié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 apparaissent en premier.
  2. Les enfants dont la valeur de la clé enfant spécifiée est false apparaissent ensuite. Si plusieurs enfants ont la valeur false, ils sont triés de manière lexicographique par clé.
  3. Les enfants dont la valeur de true pour la clé enfant spécifiée apparaissent ensuite. Si plusieurs enfants ont la valeur true, ils sont triés de manière lexicographique par clé.
  4. Les enfants ayant une valeur numérique apparaissent 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 de manière lexicographique par ordre croissant. Si plusieurs enfants ont la même valeur pour le nœud enfant spécifié, ils sont triés de manière lexicographique par clé.
  6. Les objets apparaissent en dernier et sont triés de manière lexicographique par clé par 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 comme un entier 32 bits apparaissent en premier, triés par ordre croissant.
  2. Les enfants dont la clé est une valeur de chaîne apparaissent ensuite, triés de manière lexicographique par ordre croissant.

OrderByValue

Lorsque vous utilisez OrderByValue(), les enfants sont triés par leur valeur. Les critères de tri sont les mêmes que dans OrderByChild(), sauf que la valeur du nœud est utilisée à la place de la valeur d'une clé enfant spécifiée.

Étapes suivantes