Daten werden abgerufen

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

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 Ihr Unity-Projekt bereits Firebase verwendet, 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.

Das Hinzufügen von Firebase zu Ihrem Unity-Projekt umfasst Aufgaben sowohl in der Firebase Console als auch in Ihrem geöffneten Unity-Projekt. Sie laden beispielsweise Firebase-Konfigurationsdateien aus der Console herunter und verschieben sie dann in Ihr Unity-Projekt.

Daten abrufen

Firebase-Daten werden entweder durch einen einmaligen Aufruf von GetValueAsync() abgerufen oder durch Anhängen an ein Ereignis in einer FirebaseDatabase-Referenz. Der Event-Listener wird einmal für den ursprünglichen Zustand der Daten und dann jedes Mal aufgerufen, wenn sich die Daten ändern.

DatabaseReference 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 Methode GetValueAsync können Sie einmalig 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, ist der zurückgegebene Snapshot null.

    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 Event-Listener hinzufügen, um Änderungen an Daten zu abonnieren:

Ereignis Typische Verwendung
ValueChanged Änderungen am gesamten Inhalt eines Pfads lesen und darauf reagieren
ChildAdded Listen von Elementen abrufen oder auf Ergänzungen einer Liste von Elementen warten Empfohlene Verwendung mit ChildChanged und ChildRemoved, um Änderungen an Listen zu überwachen.
ChildChanged Auf Änderungen an den Elementen in einer Liste reagieren Verwenden Sie ChildAdded und ChildRemoved, um Änderungen an Listen zu überwachen.
ChildRemoved Auf das Entfernen von Elementen aus einer Liste reagieren Verwenden Sie ChildAdded und ChildChanged, um Änderungen an Listen zu überwachen.
ChildMoved Auf Änderungen der Reihenfolge von Elementen in einer sortierten Liste reagieren ChildMoved-Ereignisse folgen immer dem ChildChanged-Ereignis, das die Änderung der Reihenfolge des Artikels verursacht hat (basierend auf Ihrer aktuellen Sortierungsmethode).

ValueChanged-Ereignis

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 untergeordneter Elemente, ändern. An den Ereignis-Callback 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:

      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 ein DataSnapshot, das die Daten am angegebenen Speicherort in der Datenbank zum Zeitpunkt des Ereignisses enthält. Wenn Sie Value für einen Snapshot aufrufen, wird ein Dictionary<string, object> zurückgegeben, das die Daten darstellt. Wenn am Standort keine Daten vorhanden sind, wird beim Aufrufen von Value der Wert null zurückgegeben.

In diesem Beispiel wird auch args.DatabaseError geprüft, um festzustellen, ob der Lesevorgang abgebrochen wurde. Ein Lesevorgang kann beispielsweise abgebrochen werden, wenn der Client keine Berechtigung zum Lesen von einem Firebase-Datenbankspeicherort hat. Im Feld DatabaseError wird angegeben, warum der Fehler aufgetreten ist.

Sie können sich später mit einem beliebigen DatabaseReference mit demselben Pfad vom Ereignis abmelden. DatabaseReference-Instanzen sind kurzlebig und können als Möglichkeit betrachtet werden, auf beliebige Pfade und Abfragen zuzugreifen.

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

Untergeordnete Ereignisse

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 Push() hinzugefügt oder ein untergeordnetes Element über die Methode UpdateChildrenAsync() aktualisiert wird. Jede dieser Methoden kann nützlich sein, um auf Änderungen an einem bestimmten Knoten in einer Datenbank zu reagieren. Ein Spiel kann diese Methoden beispielsweise zusammen verwenden, um die Aktivität in den Kommentaren einer Spielsitzung zu überwachen, wie unten gezeigt:

      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 ChildAdded-Ereignis wird einmal für jedes vorhandene untergeordnete Element und dann jedes Mal ausgelöst, 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 ChildChanged-Ereignis wird jedes Mal ausgelöst, wenn ein untergeordneter Knoten geändert wird. Das gilt auch für alle Änderungen an untergeordneten Knoten des untergeordneten Knotens. Sie wird in der Regel in Verbindung mit den Ereignissen ChildAdded und ChildRemoved verwendet, um auf Änderungen an einer Liste von Elementen zu reagieren. Der Snapshot, der an den Event-Listener übergeben wird, enthält die aktualisierten Daten für das untergeordnete Element.

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

Das Ereignis ChildMoved> wird immer dann ausgelöst, wenn das Ereignis ChildChanged durch eine Aktualisierung ausgelöst wird, die eine Neuordnung des untergeordneten Elements zur Folge hat. 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 nach einer bestimmten Anzahl von Ergebnissen oder einem Bereich von Schlüsseln oder Werten filtern.

Daten sortieren

Um sortierte Daten abzurufen, müssen Sie zuerst eine der Order-by-Methoden angeben, um die Reihenfolge der Ergebnisse festzulegen:

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

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

Im folgenden Beispiel wird gezeigt, wie Sie ein Abo für eine nach Punktzahl sortierte 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 valuechanged-Ereignis-Listener den Client mit der Bestenliste in der Datenbank synchronisiert, sortiert nach der Punktzahl der einzelnen Einträge. Weitere Informationen zum effizienten Strukturieren von Daten finden Sie unter Datenbank strukturieren.

Im 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 dazu, wie andere Datentypen sortiert werden, finden Sie unter So werden Abfragedaten sortiert.

Daten filtern

Um Daten zu filtern, können Sie beim Erstellen einer Abfrage eine beliebige der Limit- oder Bereichsmethoden mit einer Order-by-Methode kombinieren.

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

Im Gegensatz zu den Order-by-Methoden können Sie mehrere Limit- oder Range-Funktionen 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 Anfrage gibt, ist der Snapshot weiterhin 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 Callback synchronisiert werden sollen. Wenn Sie beispielsweise LimitToFirst() verwenden, um ein Limit von 100 festzulegen, erhalten Sie anfangs nur bis zu 100 ChildAdded-Callbacks. Wenn Sie weniger als 100 Elemente in Ihrer Firebase-Datenbank gespeichert haben, wird für jedes Element ein ChildAdded-Callback ausgelöst.

Wenn sich Elemente ändern, erhalten Sie ChildAdded-Callbacks für Elemente, die in die Abfrage aufgenommen werden, und ChildRemoved-Callbacks für Elemente, die aus der Abfrage entfernt werden. Die Gesamtzahl bleibt also immer bei 100.

Mit dem folgenden Code wird beispielsweise der höchste Score aus einer Bestenliste zurückgegeben:

      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 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 von den einzelnen „order by“-Methoden in der Klasse Query sortiert werden.

OrderByChild

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

  1. Kinder mit einem null-Wert für den angegebenen untergeordneten Schlüssel werden zuerst angezeigt.
  2. Als Nächstes folgen Kinder 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 Kinder 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. Danach folgen Kinder 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 auf 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.
  6. Objekte werden zuletzt aufgeführt und lexikografisch nach Schlüssel in aufsteigender Reihenfolge sortiert.

OrderByKey

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

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

OrderByValue

Bei Verwendung von OrderByValue() werden Kinder 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.