Mit Datenlisten arbeiten

Datenbankreferenz abrufen

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

DatabaseReference ref = FirebaseDatabase.instance.ref();

Listen lesen und schreiben

Daten an eine Liste anhängen

Verwenden Sie die Methode push(), um Daten an eine Liste in Mehrnutzeranwendungen anzuhängen. Die Methode push() generiert jedes Mal einen eindeutigen Schlüssel, wenn der angegebenen Firebase-Referenz ein neues untergeordnetes Element hinzugefügt wird. Durch die Verwendung dieser automatisch generierten Schlüssel für jedes neue Element in der Liste können mehrere Clients gleichzeitig untergeordnete Elemente am selben Ort hinzufügen, ohne dass es zu Schreibkonflikten kommt. Der von push() generierte eindeutige Schlüssel basiert auf einem Zeitstempel, sodass Listenelemente automatisch chronologisch sortiert werden.

Sie können die Referenz auf die neuen Daten, die von der Methode push() zurückgegeben werden, verwenden, um den Wert des automatisch generierten Schlüssels des untergeordneten Elements abzurufen oder Daten für das untergeordnete Element festzulegen. Die Eigenschaft .key einer push()-Referenz enthält den automatisch generierten Schlüssel.

Sie können diese automatisch generierten Schlüssel verwenden, um die Abflachung Ihrer Datenstruktur zu vereinfachen. Weitere Informationen finden Sie im Beispiel für die Datenverteilung.

Mit push() kann beispielsweise ein neuer Beitrag zu einer Liste von Beiträgen in einer sozialen Anwendung hinzugefügt werden:

DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
  // ...
});

Auf untergeordnete Ereignisse warten

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 push() hinzugefügt oder ein untergeordnetes Element mit der Methode update() aktualisiert wird.

Ereignis Typische Verwendung
onChildAdded Listen von Elementen abrufen oder auf Ergänzungen einer Liste von Elementen warten. Dieses Ereignis wird einmal für jedes vorhandene untergeordnete Element und dann wieder 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.
onChildChanged Auf Änderungen an den Elementen in einer Liste warten. Dieses Ereignis wird jedes Mal ausgelöst, wenn ein untergeordneter Knoten geändert wird. Dazu gehören auch alle Änderungen an den Nachfolgern des untergeordneten Knotens. Der Snapshot, der an den Ereignis-Listener übergeben wird, enthält die aktualisierten Daten für das untergeordnete Element.
onChildRemoved Auf Elemente warten, die aus einer Liste entfernt werden. Dieses Ereignis wird ausgelöst, wenn ein direkt untergeordnetes Element entfernt wird.Der Snapshot, der an den Callback-Block übergeben wird, enthält die Daten für das entfernte untergeordnete Element.
onChildMoved Auf Änderungen an der Reihenfolge von Elementen in einer sortierten Liste warten. Auf onChildMoved-Ereignisse folgt immer das onChildChanged-Ereignis, das die Änderung der Reihenfolge des Elements verursacht hat (basierend auf der aktuellen Sortiermethode).

Jedes dieser Ereignisse kann nützlich sein, um auf Änderungen an einem bestimmten Knoten in einer Datenbank zu warten. In einer sozialen Blogging-App können diese Methoden beispielsweise zusammen verwendet werden, um die Aktivitäten in den Kommentaren eines Beitrags zu beobachten, wie unten gezeigt:

final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
  // A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
  // A comment has changed; use the key to determine if we are displaying this
  // comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
  // A comment has been removed; use the key to determine if we are displaying
  // this comment and if so remove it.
});

Auf Wertereignisse warten

Das Warten auf untergeordnete Ereignisse ist zwar die empfohlene Methode zum Lesen von Datenlisten, es gibt aber auch Situationen, in denen das Warten auf Wertereignisse für eine Listenreferenz nützlich ist.

Wenn Sie einen value-Listener an eine Datenliste anhängen, wird die gesamte Datenliste als einzelner Snapshot zurückgegeben, den Sie dann durchlaufen können, um auf einzelne untergeordnete Elemente zuzugreifen.

Auch wenn es nur eine Übereinstimmung für die Abfrage gibt, ist der Snapshot immer noch eine Liste, die nur ein Element enthält. Um auf das Element zuzugreifen, müssen Sie das Ergebnis durchlaufen:

myTopPostsQuery.onValue.listen((event) {
  for (final child in event.snapshot.children) {
    // Handle the post.
  }
}, onError: (error) {
  // Error.
});

Dieses Muster kann nützlich sein, wenn Sie alle untergeordneten Elemente einer Liste in einem einzigen Vorgang abrufen möchten, anstatt auf zusätzliche Ereignisse für hinzugefügte untergeordnete Elemente zu warten.

Daten sortieren und filtern

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

Daten sortieren

Um sortierte Daten abzurufen, geben Sie zuerst eine der Sortiermethoden an, um festzulegen, wie die Ergebnisse sortiert werden:

Methode Nutzung
orderByChild() Ergebnisse nach dem Wert eines angegebenen untergeordneten Schlüssels oder eines verschachtelten untergeordneten Pfads 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.

Das folgende Beispiel zeigt, wie Sie eine Liste der Top-Beiträge eines Nutzers nach der Anzahl der Sterne sortiert abrufen können:

final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
    .ref("user-posts/$myUserId")
    .orderByChild("starCount");

Hier wird eine Abfrage definiert, die in Kombination mit einem Listener für untergeordnete Elemente den Client mit den Beiträgen des Nutzers aus dem Pfad in der Datenbank synchronisiert basierend auf der Nutzer-ID und sortiert nach der Anzahl der Sterne, die jeder Beitrag erhalten hat. Diese Technik, IDs als Indexschlüssel zu verwenden, wird als Datenverteilung bezeichnet. Weitere Informationen 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 Beiträge nach dem Wert des jeweiligen untergeordneten Elements "starCount" sortiert. Abfragen können auch nach verschachtelten untergeordneten Elementen sortiert werden, wenn Ihre Daten so aussehen:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

In diesem Fall können wir unsere Listenelemente nach Werten sortieren, die unter dem Schlüssel metrics verschachtelt sind, indem wir den relativen Pfad zum verschachtelten untergeordneten Element in unserem orderByChild()-Aufruf angeben.

final mostViewedPosts =
    FirebaseDatabase.instance.ref('posts').orderByChild('metrics/views');

Weitere Informationen zur Sortierung anderer Datentypen finden Sie unter So werden Abfragedaten sortiert.

Daten filtern

Zum Filtern von Daten können Sie beim Erstellen einer Abfrage eine beliebige Limit- oder Bereichsmethode 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.
startAfter() Gibt Elemente zurück, die größer als der angegebene 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.
endBefore() Gibt Elemente zurück, die kleiner als der angegebene 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 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.

Anzahl der Ergebnisse begrenzen

Mit den Methoden limitToFirst() und limitToLast() können Sie die maximale Anzahl der untergeordneten Elemente festlegen, die für ein bestimmtes Ereignis synchronisiert werden sollen. Wenn Sie beispielsweise mit limitToFirst() ein Limit von 100 festlegen, erhalten Sie zunächst nur bis zu 100 onChildAdded-Ereignisse. Wenn in Ihrer Firebase-Datenbank weniger als 100 Elemente gespeichert sind, wird für jedes Element ein onChildAdded-Ereignis ausgelöst.

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

Das folgende Beispiel zeigt, wie in der Blogging-Beispiel-App eine Abfrage definiert wird, um eine Liste der 100 neuesten Beiträge aller Nutzer abzurufen:

final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);

In diesem Beispiel wird nur eine Abfrage definiert. Um Daten tatsächlich zu synchronisieren, muss ein Listener angehängt sein.

Nach Schlüssel oder Wert filtern

Mit startAt(), startAfter(), endAt(), endBefore() 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, 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 kommen als Nächstes. Wenn mehrere untergeordnete Elemente den Wert false haben, werden sie lexikografischsortiert nach Schlüssel.
  3. Als Nächstes folgen untergeordnete Elemente mit dem Wert true für den angegebenen untergeordneten Schlüssel kommen als Nächstes. 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 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.
  6. Objekte werden zuletzt angezeigt und lexikografisch nach Schlüssel in aufsteigender Reihenfolge sortiert.

orderByKey

Bei Verwendung von orderByKey() zum Sortieren von Daten 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, sortiert lexikografisch in aufsteigender Reihenfolge.

orderByValue

Bei Verwendung von orderByValue() werden untergeordnete Elemente nach ihrem Wert sortiert. Die Sortierkriterien sind dieselben wie bei orderByChild(), nur dass der Wert des Knotens anstelle des Werts eines angegebenen untergeordneten Schlüssels verwendet wird.

Listener trennen

Callbacks werden entfernt, indem Sie die Methode off() für Ihre Firebase-Datenbankreferenz aufrufen.

Sie können einen einzelnen Listener entfernen, indem Sie ihn als Parameter an off() übergeben. Wenn Sie off() ohne Argumente für den Speicherort aufrufen, werden alle Listener an diesem Speicherort entfernt.

Wenn Sie off() für einen übergeordneten Listener aufrufen, werden Listener, die für die untergeordneten Knoten registriert sind, nicht automatisch entfernt. off() muss auch für alle untergeordneten Listener aufgerufen werden, um den Callback zu entfernen.

Nächste Schritte