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

In diesem Dokument werden die Grundlagen des Abrufens von Daten und die Sortierung und Filterung von Firebase-Daten erläutert.

Hinweis

Achte darauf, dass du deine App eingerichtet hast und auf die Datenbank zugreifen kannst, wie im Leitfaden für Get Started beschrieben.

Daten abrufen

Firebase-Daten werden entweder durch einen einmaligen Aufruf von GetValue() oder durch Anhängen an eine ValueListener an einer FirebaseDatabase-Referenz abgerufen. Der Wert-Listener wird einmal für den anfänglichen Status der Daten und dann bei jeder Änderung der Daten aufgerufen.

Datenbankreferenz abrufen

Zum Schreiben von Daten in die Datenbank benötigen Sie eine Instanz von DatabaseReference:

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

Daten einmal lesen

Mit der GetValue()-Methode können Sie einmal einen statischen Snapshot des Inhalts an einem bestimmten Pfad lesen. Das Aufgabenergebnis enthält einen Snapshot mit allen Daten an diesem Speicherort, einschließlich untergeordneter Daten. Wenn keine Daten vorhanden sind, wird null zurückgegeben.

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

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

  // 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 sehen Sie eine grundlegende Fehlerprüfung. Weitere Informationen zur Fehlerprüfung und dazu, wie Sie feststellen können, wann das Ergebnis bereit ist, finden Sie in der Referenz firebase::Future.

Auf Ereignisse warten

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

ValueListener Basisklasse

Rückruf Normale Nutzung
OnValueChanged Änderungen am gesamten Inhalt eines Pfads lesen und beobachten.

OnChildListener Basisklasse

OnChildAdded Listen mit Elementen abrufen oder nach Elementen suchen, die einer Liste hinzugefügt wurden Empfohlene Verwendung mit OnChildChanged und OnChildRemoved, um Änderungen an Listen zu beobachten.
OnChildChanged Beobachten Sie Änderungen an den Elementen in einer Liste. Verwenden Sie OnChildAdded und OnChildRemoved, um Änderungen an Listen im Blick zu behalten.
OnChildRemoved Beobachten Sie, ob Elemente aus einer Liste entfernt werden. Verwende OnChildAdded und OnChildChanged, um Änderungen an Listen zu beobachten.
OnChildMoved Beobachten Sie Änderungen an der Reihenfolge der Elemente in einer geordneten Liste. OnChildMoved-Callbacks folgen immer den OnChildChanged-Callbacks, da sich die Reihenfolge des Artikels (basierend auf deiner aktuellen Order-by-Methode) ändert.

ValueListener-Klasse

Mit den OnValueChanged-Callbacks kannst du Änderungen am Inhalt an einem bestimmten Pfad 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. Dem Rückruf wird ein Snapshot mit allen Daten an diesem Speicherort übergeben, einschließlich untergeordneter Daten. Wenn keine Daten vorhanden sind, wird als Snapshot null zurückgegeben.

Das folgende Beispiel zeigt ein Spiel, das 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 eine Variant zurückgegeben, die die Daten darstellt.

In diesem Beispiel wird auch die OnCancelled-Methode überschrieben, um zu prüfen, ob die Lesevorgänge abgebrochen werden. Ein Lesevorgang kann beispielsweise abgebrochen werden, wenn der Client keine Leseberechtigung für einen Firebase-Datenbankspeicherort hat. Die database::Error gibt an, warum der Fehler aufgetreten ist.

Klasse „ChildListener“

Untergeordnete Ereignisse werden als Reaktion auf bestimmte Vorgänge ausgelöst, die mit den untergeordneten Elementen eines Knotens durch einen Vorgang stattfinden, z. B. wenn ein neues untergeordnetes Element über die Methode PushChild() hinzugefügt oder ein untergeordnetes Element über die Methode UpdateChildren() aktualisiert wird. Zusammen können sie nützlich sein, um Änderungen an einem bestimmten Knoten in einer Datenbank zu beobachten. Ein Spiel könnte beispielsweise diese Methoden zusammen verwenden, um die Aktivität in den Kommentaren einer Spielsitzung zu überwachen, wie unten dargestellt:

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

Der OnChildChanged-Callback wird immer dann aufgerufen, wenn ein untergeordneter Knoten geändert wird. Dies schließt alle Änderungen an Nachfolgerelementen des untergeordneten Knotens ein. Sie wird in der Regel 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 OnChildRemoved-Callback wird ausgelöst, wenn ein unmittelbares untergeordnetes Element entfernt wird. Sie wird in der Regel in Verbindung mit den OnChildAdded- und OnChildChanged-Callbacks verwendet. Der an den Rückruf übergebene Snapshot enthält die Daten für das entfernte untergeordnete Element.

Der OnChildMoved-Callback wird ausgelöst, wenn der OnChildChanged-Aufruf durch eine Aktualisierung ausgelöst wird, die eine Neusortierung des untergeordneten Elements zur Folge hat. Sie wird für Daten verwendet, die mit OrderByChild oder OrderByValue sortiert sind.

Daten sortieren und filtern

Mit der Klasse Realtime Database Query können Sie Daten nach Schlüssel, Wert oder Wert eines untergeordneten Elements abrufen. Sie können die sortierten Ergebnisse auch auf eine bestimmte Anzahl von Ergebnissen oder einen Bereich von Schlüsseln oder Werten begrenzen.

Daten sortieren

Wenn Sie sortierte Daten abrufen möchten, müssen Sie zuerst eine der Sortierungsmethoden angeben, um zu bestimmen, wie die Ergebnisse sortiert werden:

Methode Nutzung
OrderByChild() Sortiert die Ergebnisse nach dem Wert eines bestimmten untergeordneten Schlüssels.
OrderByKey() Ergebnisse nach untergeordneten Schlüsseln sortieren
OrderByValue() Sortieren Sie die Ergebnisse nach untergeordneten Werten.

Sie können jeweils nur eine Sortiermethode verwenden. Wenn Sie eine Methode zum Sortieren mehrmals in derselben Abfrage aufrufen, wird ein Fehler ausgegeben.

Im folgenden Beispiel wird gezeigt, 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.

Dadurch wird eine firebase::Query definiert, die in Kombination mit einem ValueListener den Client mit der Bestenliste in der Datenbank synchronisiert, die nach dem Wert jedes Eintrags sortiert ist. Weitere Informationen zum effizienten Strukturieren Ihrer Daten finden Sie unter Datenbank strukturieren.

Der Aufruf der Methode OrderByChild() gibt den untergeordneten Schlüssel an, nach dem die Ergebnisse sortiert werden sollen. In diesem Fall werden die Ergebnisse nach dem Wert des "score"-Werts in den einzelnen untergeordneten Elementen 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 der Methoden zum Begrenzen oder Bestimmen des Bereichs mit einer Sortiermethode kombinieren.

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

Im Gegensatz zu den Sortiermethoden 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 Übereinstimmung für die Suchanfrage gibt, ist der Snapshot immer eine Liste. Er enthält nur ein einzelnes Element.

Anzahl der Ergebnisse begrenzen

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

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

Der folgende Code gibt beispielsweise den höchsten Wert 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

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

Sortierung von Abfragedaten

In diesem Abschnitt wird erläutert, wie Daten mit den einzelnen Sortierungsmethoden in der Query-Klasse sortiert werden.

OrderByChild

Bei Verwendung von OrderByChild() werden Daten, die den angegebenen untergeordneten Schlüssel enthalten, so sortiert:

  1. Untergeordnete Elemente mit einem null-Wert für den angegebenen untergeordneten Schlüssel werden zuerst angezeigt.
  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 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 folgen nach Zahlen und werden alphabetisch in aufsteigender Reihenfolge sortiert. Wenn mehrere untergeordnete Elemente denselben Wert für den angegebenen untergeordneten Knoten haben, werden sie nach Schlüssel sortiert.
  6. Objekte kommen zuletzt und werden in aufsteigender Reihenfolge nach Schlüssel sortiert.

OrderByKey

Wenn Sie Ihre Daten mit OrderByKey() sortieren, werden sie 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 in aufsteigender Reihenfolge sortiert.
  2. Als Nächstes kommen untergeordnete Elemente, deren Schlüssel einen Stringwert enthält. Sie werden lexikografisch in aufsteigender Reihenfolge sortiert.

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