In diesem Dokument werden die Grundlagen des Abrufens von Daten und des Sortierens und Filterns von Firebase-Daten behandelt.
Hinweis
Achten Sie darauf, dass Sie Ihre App eingerichtet haben und auf die Datenbank zugreifen können, wie in
dem Get Started Leitfaden beschrieben.
Daten abrufen
Firebase-Daten werden entweder durch einen einmaligen Aufruf von GetValue() oder durch Anhängen an einen 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.
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 einmal lesen
Mit der Methode GetValue() können Sie einmal einen statischen Snapshot der Inhalte 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, ist der zurückgegebene Snapshot null.
firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").GetValue();
An diesem Punkt wurde die Anfrage gestellt, aber wir müssen warten, bis die Future abgeschlossen ist, bevor wir den Wert lesen können. Da Spiele in der Regel in einer Schleife ausgeführt werden und weniger auf Rückrufen basieren 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 wird eine grundlegende Fehlerprüfung gezeigt. Weitere Informationen zur Fehlerprüfung und zu Möglichkeiten, zu ermitteln, wann das Ergebnis bereit ist, finden Sie in der firebase::Future Referenz zu firebase::Future.
Auf Ereignisse warten
Sie können Listener hinzufügen, um Änderungen an Daten zu abonnieren:
Basisklasse ValueListener
| Rückruf | Typische Verwendung |
|---|---|
OnValueChanged |
Änderungen am gesamten Inhalt eines Pfads lesen und beobachten. |
Basisklasse OnChildListener
OnChildAdded
| Listen von Elementen abrufen oder auf Ergänzungen einer Liste von Elementen warten.
Empfohlene Verwendung mit OnChildChanged und
OnChildRemoved um Änderungen an Listen zu beobachten. |
OnChildChanged |
Auf Änderungen an den Elementen in einer Liste warten. Verwendung mit
OnChildAdded und OnChildRemoved, um Änderungen an Listen zu beobachten. |
OnChildRemoved |
Auf Elemente warten, die aus einer Liste entfernt werden. Verwendung mit
OnChildAdded und OnChildChanged, um
Änderungen an Listen zu beobachten. |
OnChildMoved |
Auf Änderungen an der Reihenfolge von Elementen in einer sortierten Liste warten.
OnChildMoved Rückrufe folgen immer den
OnChildChanged Rückrufen, da sich die Reihenfolge des Elements
ändert (basierend auf der aktuellen Sortiermethode). |
Klasse `ValueListener`
Mit den OnValueChanged-Rückrufen können Sie Änderungen an den Inhalten an einem bestimmten Pfad abonnieren. Dieser Rückruf wird einmal ausgelöst, wenn der Listener angehängt wird, und dann jedes Mal, wenn sich die Daten, einschließlich untergeordneter Elemente, ändern. An den Rückruf wird ein Snapshot mit allen Daten an diesem Speicherort übergeben, einschließlich untergeordneter Daten. Wenn keine Daten vorhanden sind, ist der zurückgegebene Snapshot null.
Im folgenden Beispiel ruft ein Spiel die Ergebnisse einer Bestenliste aus der Datenbank ab:
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<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").AddValueListener(listener);
Das Future<DataSnapshot> 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 Methode OnCancelled überschrieben, um zu prüfen, ob der Lesevorgang abgebrochen wurde. Ein Lesevorgang kann beispielsweise abgebrochen werden, wenn der Client keine Berechtigung zum Lesen von einem Firebase-Datenbankspeicherort hat. Der 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 ausgeführt werden, z. B. wenn ein neues untergeordnetes Element mit der Methode PushChild() hinzugefügt oder ein untergeordnetes Element mit der Methode UpdateChildren() aktualisiert wird. Jeder dieser Vorgänge kann nützlich sein, um Änderungen an einem bestimmten Knoten in einer Datenbank zu beobachten. Ein Spiel kann diese Methoden beispielsweise zusammen verwenden, um die Aktivität in den Kommentaren einer Spielsitzung zu beobachten, 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<firebase::database::DataSnapshot> result = dbRef.GetReference("GameSessionComments").AddChildListener(listener);
Der Rückruf OnChildAdded wird in der Regel verwendet, um eine Liste von Elementen in einer Firebase-Datenbank abzurufen. Der Rückruf OnChildAdded wird einmal für jedes vorhandene untergeordnete Element und dann jedes Mal aufgerufen, 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 Rückruf OnChildChanged wird jedes Mal aufgerufen, wenn ein untergeordneter Knoten geändert wird.
Dazu gehören alle Änderungen an den Nachfolgern des untergeordneten Knotens. Er 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 Rückruf OnChildRemoved wird ausgelöst, wenn ein direkt untergeordnetes Element entfernt wird.
Er wird in der Regel in Verbindung mit den Rückrufen OnChildAdded und OnChildChanged verwendet. Der an den Rückruf übergebene Snapshot enthält die Daten für das entfernte untergeordnete Element.
Der Rückruf OnChildMoved wird ausgelöst, wenn der Aufruf OnChildChanged durch eine Aktualisierung ausgelöst wird, die eine Neuanordnung des untergeordneten Elements verursacht. Er 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 nach
Schlüssel, Wert oder Wert eines untergeordneten Elements sortieren. 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 Sortiermethoden an, um zu bestimmen, wie die Ergebnisse sortiert werden:
| Methode | Nutzung |
|---|---|
OrderByChild() |
Ergebnisse nach dem Wert eines bestimmten untergeordneten Schlüssels sortieren. |
OrderByKey()
| Ergebnisse nach untergeordneten Schlüsseln sortieren. |
OrderByValue() |
Ergebnisse nach untergeordneten Werten sortieren. |
Sie können jeweils nur eine Sortiermethode verwenden. Wenn Sie in derselben Abfrage mehrere Sortiermethoden aufrufen, wird ein Fehler ausgelöst.
Im folgenden Beispiel wird gezeigt, wie Sie eine Bestenliste abonnieren können, die nach Ergebnis 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, sortiert nach dem Ergebnis jedes Eintrags.
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 von "score"
Wert in jedem untergeordneten Element sortiert. Weitere Informationen zur Sortierung anderer Datentypen finden Sie unter So werden Abfragedaten sortiert.
Daten filtern
Wenn Sie Daten filtern möchten, können Sie beim Erstellen einer Abfrage eine der Methoden für Limit oder Bereich 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 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 Sortiermethode. |
EndAt() |
Gibt Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind je nach gewählter Sortiermethode. |
EqualTo() |
Gibt Elemente zurück, die gleich dem angegebenen Schlüssel oder Wert sind je nach gewählter 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 Abfrage gibt, ist der Snapshot eine Liste, die nur ein Element enthält.
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 zunächst nur bis zu 100 OnChildAdded-Rückrufe. Wenn in Ihrer Firebase-Datenbank weniger als 100 Elemente gespeichert sind, wird für jedes Element ein OnChildAdded-Rückruf ausgelöst.
Wenn sich Elemente ändern, erhalten Sie OnChildAdded-Rückrufe für Elemente, die in die Abfrage aufgenommen werden, und OnChildRemoved-Rückrufe für Elemente, die daraus entfernt werden, sodass die Gesamtzahl bei 100 bleibt.
Der folgende Code gibt beispielsweise das beste Ergebnis 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 mit den einzelnen Sortiermethoden in der Klasse Query sortiert werden.
OrderByChild
Bei Verwendung von OrderByChild() werden Daten, die den angegebenen untergeordneten Schlüssel enthalten, wie folgt sortiert:
- Untergeordnete Elemente mit dem Wert
nullfür den angegebenen untergeordneten Schlüssel werden zuerst angezeigt. - Untergeordnete Elemente mit dem Wert
falsefür den angegebenen untergeordneten Schlüssel werden als Nächstes angezeigt. Wenn mehrere untergeordnete Elemente den Wertfalsehaben, werden sie lexikografischsortiert nach Schlüssel. - Untergeordnete Elemente mit dem Wert
truefür den angegebenen untergeordneten Schlüssel werden als Nächstes angezeigt. Wenn mehrere untergeordnete Elemente den Werttruehaben, werden sie lexikografisch nach Schlüssel sortiert. - Untergeordnete Elemente mit einem numerischen Wert werden als Nächstes angezeigt, sortiert in aufsteigender Reihenfolge. Wenn mehrere untergeordnete Elemente denselben numerischen Wert für den angegebenen untergeordneten Knoten haben, werden sie nach Schlüssel sortiert.
- Strings folgen nach Zahlen und werden 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.
- Objekte werden zuletzt angezeigt und 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.
- Untergeordnete Elemente mit einem Schlüssel, der als 32-Bit-Ganzzahl geparst werden kann, werden zuerst angezeigt, sortiert in aufsteigender Reihenfolge.
- Untergeordnete Elemente mit einem Stringwert als Schlüssel werden als Nächstes angezeigt, sortiert lexikografisch in aufsteigender Reihenfolge.
OrderByValue
Bei Verwendung von OrderByValue() werden untergeordnete Elemente nach ihrem Wert sortiert. Die Sortierkriterien sind dieselben wie bei OrderByChild(), außer dass der Wert des Knotens anstelle des Werts eines bestimmten untergeordneten Schlüssels verwendet wird.