Daten mit Firebase Realtime Database für C++ abrufen

In diesem Dokument werden die Grundlagen des Abrufens von Daten sowie das Sortieren und Filtern von Firebase-Daten behandelt.

Hinweis

Richten Sie Ihre Anwendung ein und sorgen Sie dafür, dass Sie auf die Datenbank zugreifen können, wie im Leitfaden zu Get Started beschrieben.

Daten abrufen

Firebase-Daten werden entweder durch einen einmaligen Aufruf von GetValue() oder durch Anhängen an ein ValueListener für eine FirebaseDatabase-Referenz abgerufen. Der Wert-Listener wird einmal für den Anfangszustand der Daten und dann jedes Mal aufgerufen, wenn sich die Daten ändern.

DatabaseReference abrufen

Wenn Sie Daten in die Datenbank schreiben möchten, benötigen Sie eine Instanz von DatabaseReference:

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

Daten einmalig lesen

Mit der Methode GetValue() können Sie einen statischen Snapshot des Inhalts eines bestimmten Pfads einmalig lesen. Das Taskergebnis enthält einen Snapshot mit allen Daten an diesem Speicherort, einschließlich untergeordneter Daten. Wenn keine Daten vorhanden sind, ist der zurückgegebene Snapshot null.

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

An diesem Punkt wurde die Anfrage gestellt, aber wir müssen warten, bis das Future abgeschlossen ist, bevor wir den Wert lesen können. Da Spiele in der Regel in einer Schleife ausgeführt werden und weniger Callback-gesteuert sind als andere Anwendungen, wird normalerweise der Abschluss abgefragt.

  // 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...
    }
  }

Hier wird eine einfache Fehlerprüfung gezeigt. Weitere Informationen zur Fehlerprüfung und dazu, wie Sie feststellen können, wann das Ergebnis bereit ist, finden Sie in der Referenz zu firebase::Future.

Auf Ereignisse warten

Sie können Listener hinzufügen, um über Änderungen an Daten informiert zu werden:

ValueListener-Basisklasse

Rückruf Typische Verwendung
OnValueChanged Änderungen am gesamten Inhalt eines Pfads lesen und darauf warten.

OnChildListener-Basisklasse

OnChildAdded Listen mit Elementen abrufen oder auf Ergänzungen zu einer Liste mit Elementen warten. Empfohlene Verwendung mit OnChildChanged und OnChildRemoved, um Änderungen an Listen zu beobachten.
OnChildChanged Änderungen an den Elementen in einer Liste beobachten. Verwenden Sie sie mit OnChildAdded und OnChildRemoved, um Änderungen an Listen zu beobachten.
OnChildRemoved Auf das Entfernen von Elementen aus einer Liste warten. Verwenden Sie sie mit OnChildAdded und OnChildChanged, um Änderungen an Listen zu beobachten.
OnChildMoved Änderungen an der Reihenfolge der Elemente in einer sortierten Liste überwachen. OnChildMoved-Callbacks folgen immer den OnChildChanged-Callbacks, da sich die Reihenfolge des Elements ändert (basierend auf der aktuellen order by-Methode).

ValueListener-Klasse

Mit den OnValueChanged-Callbacks können Sie Änderungen am Inhalt eines bestimmten Pfads abonnieren. Dieser Callback wird einmal ausgelöst, wenn der Listener angehängt wird, und dann jedes Mal, wenn sich die Daten, einschließlich der untergeordneten Elemente, ändern. An den Callback wird ein Snapshot übergeben, der alle Daten an diesem Speicherort enthält, einschließlich untergeordneter Daten. Wenn keine Daten vorhanden sind, wird der Snapshot null zurückgegeben.

Das folgende Beispiel zeigt, wie ein Spiel die Punktzahlen einer Bestenliste aus der Datenbank abruft:

  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);

Das Future&ltDataSnapshot&gt-Ergebnis enthält die Daten am angegebenen Speicherort in der Datenbank zum Zeitpunkt des Ereignisses. Wenn Sie value() für einen Snapshot aufrufen, wird ein Variant zurückgegeben, das die Daten darstellt.

In diesem Beispiel wird auch die Methode OnCancelled überschrieben, um zu prüfen, ob der Lesevorgang abgebrochen wird. Ein Lesevorgang kann beispielsweise abgebrochen werden, wenn der Client keine Berechtigung zum Lesen von einem Firebase-Datenbankspeicherort hat. In der database::Error wird angegeben, warum der Fehler aufgetreten ist.

ChildListener-Klasse

Untergeordnete Ereignisse werden als Reaktion auf bestimmte Vorgänge ausgelöst, die für die untergeordneten Elemente eines Knotens ausgeführt werden, z. B. wenn ein neues untergeordnetes Element über die Methode PushChild() hinzugefügt oder ein untergeordnetes Element über die Methode UpdateChildren() aktualisiert wird. Beide zusammen können nützlich sein, um auf Änderungen an einem bestimmten Knoten in einer Datenbank zu reagieren. In einem Spiel können diese Methoden beispielsweise zusammen verwendet werden, um die Aktivität in den Kommentaren einer Spielsitzung zu überwachen, wie unten gezeigt:

  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);

Der Callback OnChildAdded wird normalerweise verwendet, um eine Liste von Elementen in einer Firebase-Datenbank abzurufen. Der Callback OnChildAdded wird einmal für jedes vorhandene untergeordnete Element aufgerufen und dann jedes Mal, wenn dem angegebenen Pfad ein neues untergeordnetes Element hinzugefügt wird. An den Listener wird ein Snapshot mit den Daten des neuen untergeordneten Elements übergeben.

Der Callback OnChildChanged wird immer dann aufgerufen, wenn ein untergeordneter Knoten geändert wird. Dies schließt alle Änderungen an untergeordneten Knoten des untergeordneten Knotens ein. Sie wird normalerweise in Verbindung mit den Aufrufen OnChildAdded und OnChildRemoved verwendet, um auf Änderungen an einer Liste von Elementen zu reagieren. Der an den Listener übergebene Snapshot enthält die aktualisierten Daten für das untergeordnete Element.

Der Callback OnChildRemoved wird ausgelöst, wenn ein direktes untergeordnetes Element entfernt wird. Sie wird normalerweise in Verbindung mit den Callbacks OnChildAdded und OnChildChanged verwendet. Der an den Callback übergebene Snapshot enthält die Daten für das entfernte untergeordnete Element.

Der OnChildMoved-Callback wird immer dann ausgelöst, wenn der OnChildChanged-Aufruf durch ein Update ausgelöst wird, das eine Neuanordnung des untergeordneten Elements verursacht. Sie wird mit Daten verwendet, die mit OrderByChild oder OrderByValue sortiert sind.

Daten sortieren und filtern

Mit der Klasse Realtime Database Query können Sie Daten abrufen, die nach Schlüssel, Wert oder Wert eines untergeordneten Elements sortiert sind. Sie können das sortierte Ergebnis auch auf eine bestimmte Anzahl von Ergebnissen oder einen Bereich von Schlüsseln oder Werten filtern.

Daten sortieren

Wenn Sie sortierte Daten abrufen möchten, geben Sie zuerst eine der order by-Methoden an, um festzulegen, wie die Ergebnisse sortiert werden sollen:

Methode Nutzung
OrderByChild() Ordnet die Ergebnisse nach dem Wert eines angegebenen untergeordneten Schlüssels.
OrderByKey() Ergebnisse nach untergeordneten Schlüsseln sortieren.
OrderByValue() Ergebnisse nach untergeordneten Werten sortieren.

Sie können jeweils nur eine order by-Methode verwenden. Wenn eine order by-Methode mehrmals in derselben Abfrage aufgerufen wird, wird ein Fehler ausgegeben.

Das folgende Beispiel zeigt, wie Sie eine Bestenliste abonnieren können, die nach Punktzahl sortiert ist.

  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.

Damit wird ein firebase::Query definiert, das in Kombination mit einem ValueListener den Client mit der Bestenliste in der Datenbank synchronisiert, sortiert nach der Punktzahl der einzelnen Einträge. Weitere Informationen zur effizienten Strukturierung Ihrer Daten finden Sie unter Datenbank strukturieren.

Beim Aufruf der Methode OrderByChild() wird der untergeordnete Schlüssel angegeben, nach dem die Ergebnisse sortiert werden sollen. In diesem Fall werden die Ergebnisse nach dem Wert von "score" in jedem untergeordneten Element sortiert. Weitere Informationen zur Sortierung anderer Datentypen finden Sie unter Sortierung von Abfragedaten.

Daten filtern

Wenn Sie Daten filtern möchten, können Sie beim Erstellen einer Abfrage eine beliebige Limit- oder Bereichsmethode mit einer order by-Methode kombinieren.

Methode Nutzung
LimitToFirst() Legt die maximale Anzahl von Elementen fest, die ab dem Anfang der sortierten Ergebnisliste zurückgegeben werden sollen.
LimitToLast() Legt die maximale Anzahl der Elemente fest, die vom Ende der sortierten Ergebnisliste zurückgegeben werden sollen.
StartAt() Gibt Elemente zurück, die größer oder gleich dem angegebenen Schlüssel oder Wert sind, je nach gewählter order by-Methode.
EndAt() Gibt Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind, je nach gewählter order by-Methode.
EqualTo() Gibt Elemente zurück, die dem angegebenen Schlüssel oder Wert entsprechen, je nach gewählter order by-Methode.

Im Gegensatz zu den order by-Methoden können Sie mehrere Limit- oder Bereichsfunktionen kombinieren. Sie können beispielsweise die Methoden StartAt() und EndAt() kombinieren, um die Ergebnisse auf einen bestimmten Wertebereich zu beschränken.

Auch wenn es nur eine einzige Übereinstimmung für die Abfrage gibt, ist der Snapshot immer noch eine Liste, die nur ein einzelnes Element enthält.

Anzahl der Ergebnisse begrenzen

Mit den Methoden LimitToFirst() und LimitToLast() können Sie die maximale Anzahl von untergeordneten Elementen festlegen, die für einen bestimmten Callback synchronisiert werden sollen. Wenn Sie beispielsweise mit LimitToFirst() ein Limit von 100 festlegen, erhalten Sie anfangs nur bis zu 100 OnChildAdded-Callbacks. Wenn weniger als 100 Elemente in Ihrer Firebase-Datenbank gespeichert sind, wird für jedes Element ein OnChildAdded-Callback ausgelöst.

Wenn sich Elemente ändern, erhalten Sie OnChildAdded-Callbacks für Elemente, die in die Abfrage aufgenommen werden, und OnChildRemoved-Callbacks für Elemente, die aus der Abfrage entfernt werden, sodass die Gesamtzahl bei 100 bleibt.

Der folgende Code gibt beispielsweise die Höchstpunktzahl aus einer Bestenliste zurück:

  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.

Nach Schlüssel oder Wert filtern

Mit StartAt(), EndAt() und EqualTo() können Sie beliebige Start-, End- und Äquivalenzpunkte für Abfragen auswählen. Das kann nützlich sein, um Daten zu paginieren oder Elemente mit untergeordneten Elementen zu finden, die einen bestimmten Wert haben.

So werden Abfragedaten sortiert

In diesem Abschnitt wird erläutert, wie Daten nach den einzelnen order-by-Methoden in der Klasse Query sortiert werden.

OrderByChild

Wenn Sie OrderByChild() verwenden, werden Daten, die den angegebenen untergeordneten Schlüssel enthalten, so sortiert:

  1. Untergeordnete Elemente mit dem Wert null für den angegebenen untergeordneten Schlüssel stehen an erster Stelle.
  2. Als Nächstes folgen untergeordnete Elemente mit dem Wert false für den angegebenen untergeordneten Schlüssel. Wenn mehrere untergeordnete Elemente den Wert false haben, werden sie lexikografisch nach Schlüssel sortiert.
  3. Als Nächstes folgen untergeordnete Elemente mit dem Wert true für den angegebenen untergeordneten Schlüssel. Wenn mehrere untergeordnete Elemente den Wert true haben, werden sie lexikografisch nach Schlüssel sortiert.
  4. Als Nächstes folgen untergeordnete Elemente mit einem numerischen Wert, sortiert in aufsteigender Reihenfolge. Wenn mehrere untergeordnete Elemente denselben numerischen Wert für den angegebenen untergeordneten Knoten haben, werden sie nach Schlüssel sortiert.
  5. Strings werden nach Zahlen aufgeführt und lexikografisch in aufsteigender Reihenfolge sortiert. Wenn mehrere untergeordnete Elemente denselben Wert für den angegebenen untergeordneten Knoten haben, werden sie lexikografisch nach Schlüssel sortiert.
  6. Objekte kommen zuletzt und werden lexikografisch nach Schlüssel in aufsteigender Reihenfolge sortiert.

OrderByKey

Wenn Sie OrderByKey() zum Sortieren Ihrer Daten verwenden, werden die Daten in aufsteigender Reihenfolge nach Schlüssel zurückgegeben.

  1. Untergeordnete Elemente mit einem Schlüssel, der als 32-Bit-Ganzzahl geparst werden kann, werden zuerst angezeigt, sortiert in aufsteigender Reihenfolge.
  2. Als Nächstes folgen untergeordnete Elemente mit einem Stringwert als Schlüssel, die lexikografisch in aufsteigender Reihenfolge sortiert sind.

OrderByValue

Bei Verwendung von OrderByValue() werden untergeordnete Elemente nach ihrem Wert sortiert. Die Sortierkriterien sind dieselben wie in OrderByChild(), mit der Ausnahme, dass der Wert des Knotens anstelle des Werts eines angegebenen untergeordneten Schlüssels verwendet wird.

Nächste Schritte