Daten werden abgerufen

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

Hinweis

Bevor Sie Realtime Database verwenden können, müssen Sie Folgendes tun:

  • Registrieren Sie Ihr Unity-Projekt und konfigurieren Sie es für die Verwendung von Firebase.

    • Wenn in Ihrem Unity-Projekt bereits Firebase verwendet wird, ist es bereits für Firebase registriert und konfiguriert.

    • Wenn Sie kein Unity-Projekt haben, können Sie eine Beispiel-App herunterladen.

  • Fügen Sie Ihrem Unity-Projekt das Firebase Unity SDK (insbesondere FirebaseDatabase.unitypackage) hinzu.

Beachten Sie, dass das Hinzufügen von Firebase zu Ihrem Unity-Projekt sowohl Aufgaben in der Firebase-Konsole als auch in Ihrem offenen Unity-Projekt erfordert (z. B. laden Sie Firebase-Konfigurationsdateien von der Console herunter und verschieben sie dann in Ihr Unity-Projekt).

Daten abrufen

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

Datenbankreferenz abrufen

Zum Lesen von Daten aus der Datenbank benötigen Sie eine Instanz von DatabaseReference:

using Firebase;
using Firebase.Database;
using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

Daten einmal lesen

Mit der GetValueAsync-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 als Snapshot null zurückgegeben.

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWithOnMainThread(task =&gt {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

Auf Ereignisse warten

Sie können Ereignis-Listener hinzufügen, um Änderungen an Daten zu abonnieren:

Ereignis Typische Verwendung
ValueChanged Änderungen am gesamten Inhalt eines Pfads lesen und beobachten.
ChildAdded Rufen Sie Listen von Elementen ab oder achten Sie auf Ergänzungen zu einer Liste von Elementen. Empfohlene Verwendung mit ChildChanged und ChildRemoved, um Änderungen an Listen zu beobachten.
ChildChanged Auf Änderungen an den Elementen in einer Liste achten Verwenden Sie ihn zusammen mit ChildAdded und ChildRemoved, um Änderungen an Listen zu beobachten.
ChildRemoved Beobachten Sie, ob Elemente aus einer Liste entfernt werden. Verwende ChildAdded und ChildChanged, um Änderungen an Listen zu beobachten.
ChildMoved Beobachten von Änderungen an der Reihenfolge der Elemente in einer sortierten Liste ChildMoved-Ereignisse folgen immer dem ChildChanged-Ereignis, durch das sich die Reihenfolge des Artikels geändert hat (basierend auf Ihrer aktuellen Sortiermethode).

Ereignis „ValueChanged“

Mit dem Ereignis ValueChanged können Sie Änderungen am Inhalt eines bestimmten Pfads abonnieren. Dieses Ereignis 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 Ereignis-Callback wird ein Snapshot mit allen Daten an diesem Speicherort übergeben, einschließlich untergeordneter Daten. Wenn keine Daten vorhanden sind, wird null zurückgegeben.

Im folgenden Beispiel wird ein Spiel veranschaulicht, bei dem die Punktzahlen einer Bestenliste aus der Datenbank abgerufen werden:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ValueChangedEventArgs enthält eine DataSnapshot, die die Daten am angegebenen Speicherort in der Datenbank zum Zeitpunkt des Ereignisses enthält. Wenn Sie Value für einen Snapshot aufrufen, wird eine Dictionary<string, object> zurückgegeben, die die Daten darstellt. Wenn an diesem Speicherort keine Daten vorhanden sind, wird beim Aufrufen von Value null zurückgegeben.

In diesem Beispiel wird auch args.DatabaseError geprüft, um festzustellen, ob die Lesevorgänge abgebrochen werden. Ein Lesevorgang kann beispielsweise abgebrochen werden, wenn der Client keine Leseberechtigung für einen Firebase-Datenbankspeicherort hat. DatabaseError gibt an, warum der Fehler aufgetreten ist.

Sie können das Ereignis später mit einem beliebigen DatabaseReference mit demselben Pfad abbestellen. DatabaseReference-Instanzen sind sitzungsspezifisch und können als eine Möglichkeit für den Zugriff auf einen beliebigen Pfad und eine beliebige Abfrage betrachtet werden.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

Untergeordnete Ereignisse

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 Push() hinzugefügt oder ein untergeordnetes Element über die Methode UpdateChildrenAsync() 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:

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Das Ereignis ChildAdded wird in der Regel verwendet, um eine Liste von Elementen in einer Firebase-Datenbank abzurufen. Das Ereignis ChildAdded wird einmal für jedes vorhandene untergeordnete Element ausgelöst 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.

Das Ereignis ChildChanged wird jedes Mal ausgelöst, wenn ein untergeordneter Knoten geändert wird. Dies schließt alle Änderungen an Nachfolgerelementen des untergeordneten Knotens ein. Es wird in der Regel in Verbindung mit den Ereignissen ChildAdded und ChildRemoved verwendet, um auf Änderungen an einer Liste von Elementen zu reagieren. Der an den Ereignis-Listener übergebene Snapshot enthält die aktualisierten Daten für das untergeordnete Element.

Das Ereignis ChildRemoved wird ausgelöst, wenn ein unmittelbares untergeordnetes Element entfernt wird. Sie wird in der Regel in Verbindung mit den ChildAdded- und ChildChanged-Callbacks verwendet. Der Snapshot, der an den Ereignis-Callback übergeben wird, enthält die Daten für das entfernte Kind.

Das ChildMoved-Ereignis wird ausgelöst, wenn das ChildChanged-Ereignis 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

Um sortierte Daten abzurufen, geben Sie zuerst eine der Sortiermethoden an, um festzulegen, 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() Ergebnisse nach untergeordneten Werten sortieren

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

Das folgende Beispiel zeigt, wie Sie Abos auf einer nach Punktzahl sortierten Punkte-Bestenliste abschließen können.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Dadurch wird eine Abfrage definiert, die in Kombination mit einem Ereignis-Listener für „valuechanged“ 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 der Elemente fest, die vom Ende der sortierten Ergebnisliste zurückgegeben werden sollen.
StartAt() Je nach ausgewählter Sortiermethode werden Elemente zurückgegeben, 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() Je nach ausgewählter Sortiermethode werden Elemente zurückgegeben, die dem angegebenen Schlüssel oder Wert entsprechen.

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 ChildAdded-Callbacks. Wenn in deiner Firebase-Datenbank weniger als 100 Elemente gespeichert sind, wird für jedes Element ein ChildAdded-Callback ausgelöst.

Wenn sich Artikel ändern, erhalten Sie ChildAdded Callbacks für Artikel, die in die Abfrage aufgenommen werden, und ChildRemoved 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:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

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 paginatieren oder Elemente mit untergeordneten Elementen mit einem bestimmten Wert zu finden.

So werden Abfragedaten geordnet

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 geordnet:

  1. Untergeordnete Schlüssel mit einem null-Wert für den angegebenen untergeordneten Schlüssel haben Vorrang.
  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. Untergeordnete Elemente mit einem numerischen Wert kommen als Nächstes, in aufsteigender Reihenfolge sortiert. 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 folgen untergeordnete Elemente mit einem Stringwert als Schlüssel, sortiert in aufsteigender lexikografischer Reihenfolge.

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.