Mit Datenlisten im Web arbeiten

Datenbankreferenz abrufen

Wenn Sie Daten aus der Datenbank lesen oder in die Datenbank schreiben möchten, benötigen Sie eine Instanz von firebase.database.Reference:

Web

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web

var database = firebase.database();

Listen lesen und schreiben

An eine Liste mit Daten anhängen

Verwenden Sie die Methode push(), um Daten an eine Liste in Anwendungen mit mehreren Nutzern anzuhängen. Die Methode push() generiert einen eindeutigen Schlüssel, wenn der angegebenen Firebase-Referenz ein neues untergeordnetes Element hinzugefügt wird. Wenn Sie diese automatisch generierten Schlüssel für jedes neue Element in der Liste verwenden, 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. Die Listenelemente werden also automatisch chronologisch sortiert.

Sie können mit dem Verweis auf die neuen Daten, die von der Methode push() zurückgegeben werden, den Wert des automatisch generierten Schlüssels des untergeordneten Elements abrufen oder Daten für das untergeordnete Element festlegen. Das Attribut .key eines push()-Verweises enthält den automatisch generierten Schlüssel.

Mit diesen automatisch generierten Schlüsseln können Sie die Datenstruktur vereinfachen. Weitere Informationen finden Sie im Beispiel für das Fan-out von Daten.

Mit push() könnte beispielsweise ein neuer Beitrag zu einer Liste von Beiträgen in einer Social-Media-Anwendung hinzugefügt werden:

Web

import { getDatabase, ref, push, set } from "firebase/database";

// Create a new post reference with an auto-generated id
const db = getDatabase();
const postListRef = ref(db, 'posts');
const newPostRef = push(postListRef);
set(newPostRef, {
    // ...
});

Web

// Create a new post reference with an auto-generated id
var postListRef = firebase.database().ref('posts');
var newPostRef = postListRef.push();
newPostRef.set({
    // ...
});

Auf untergeordnete Ereignisse warten

Untergeordnete Ereignisse werden als Reaktion auf bestimmte Vorgänge ausgelöst, die für die untergeordneten Elemente eines Knotens erfolgen, z. B. wenn ein neues untergeordnetes Element über die Methode push() hinzugefügt oder ein untergeordnetes Element über die Methode update() aktualisiert wird.

Ereignis Typische Verwendung
child_added 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 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.
child_changed Änderungen an den Elementen in einer Liste beobachten Dieses Ereignis wird immer dann ausgelöst, wenn ein untergeordneter Knoten geändert wird. Dazu gehören auch Änderungen an untergeordneten Knoten des untergeordneten Knotens. Der Snapshot, der an den Event-Listener übergeben wird, enthält die aktualisierten Daten für das untergeordnete Element.
child_removed Auf das Entfernen von Elementen aus einer Liste reagieren Dieses Ereignis wird ausgelöst, wenn ein untergeordnetes Element entfernt wird.Der Snapshot, der an den Callback-Block übergeben wird, enthält die Daten für das entfernte untergeordnete Element.
child_moved Auf Änderungen der Reihenfolge von Elementen in einer sortierten Liste reagieren child_moved-Ereignisse folgen immer dem child_changed-Ereignis, das die Änderung der Reihenfolge des Elements verursacht hat (basierend auf Ihrer aktuellen Sortierungsmethode).

Jede dieser Methoden kann nützlich sein, um Änderungen an einem bestimmten Knoten in einer Datenbank zu beobachten. Eine Social-Blogging-App kann diese Methoden beispielsweise zusammen verwenden, um Aktivitäten in den Kommentaren eines Beitrags zu überwachen, wie unten dargestellt:

Web

import { getDatabase, ref, onChildAdded, onChildChanged, onChildRemoved } from "firebase/database";

const db = getDatabase();
const commentsRef = ref(db, 'post-comments/' + postId);
onChildAdded(commentsRef, (data) => {
  addCommentElement(postElement, data.key, data.val().text, data.val().author);
});

onChildChanged(commentsRef, (data) => {
  setCommentValues(postElement, data.key, data.val().text, data.val().author);
});

onChildRemoved(commentsRef, (data) => {
  deleteComment(postElement, data.key);
});

Web

var commentsRef = firebase.database().ref('post-comments/' + postId);
commentsRef.on('child_added', (data) => {
  addCommentElement(postElement, data.key, data.val().text, data.val().author);
});

commentsRef.on('child_changed', (data) => {
  setCommentValues(postElement, data.key, data.val().text, data.val().author);
});

commentsRef.on('child_removed', (data) => {
  deleteComment(postElement, data.key);
});

Auf Wert-Ereignisse warten

Das Beobachten von untergeordneten Ereignissen ist zwar die empfohlene Methode zum Lesen von Datenlisten, es gibt jedoch Situationen, in denen das Beobachten von Wertänderungen für eine Listenreferenz nützlich ist.

Wenn Sie einen value-Beobachter an eine Liste von Daten anhängen, wird die gesamte Liste von Daten 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 Anfrage gibt, ist der Snapshot weiterhin eine Liste, die nur ein Element enthält. Um auf das Element zuzugreifen, müssen Sie das Ergebnis durchlaufen:

Web

import { getDatabase, ref, onValue } from "firebase/database";

const db = getDatabase();
const dbRef = ref(db, '/a/b/c');

onValue(dbRef, (snapshot) => {
  snapshot.forEach((childSnapshot) => {
    const childKey = childSnapshot.key;
    const childData = childSnapshot.val();
    // ...
  });
}, {
  onlyOnce: true
});

Web

ref.once('value', (snapshot) => {
  snapshot.forEach((childSnapshot) => {
    var childKey = childSnapshot.key;
    var childData = childSnapshot.val();
    // ...
  });
});

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 vom Typ „child added“ zu warten.

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

Wenn Sie sortierte Daten abrufen möchten, geben Sie zuerst eine der Order-by-Methoden an, um die Reihenfolge der Ergebnisse festzulegen:

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 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 eine Liste der Top-Beiträge eines Nutzers abrufen, sortiert nach der Anzahl der Sterne:

Web

import { getDatabase, ref, query, orderByChild } from "firebase/database";
import { getAuth } from "firebase/auth";

const db = getDatabase();
const auth = getAuth();

const myUserId = auth.currentUser.uid;
const topUserPostsRef = query(ref(db, 'user-posts/' + myUserId), orderByChild('starCount'));

Web

var myUserId = firebase.auth().currentUser.uid;
var topUserPostsRef = firebase.database().ref('user-posts/' + myUserId).orderByChild('starCount');

Dadurch wird eine Abfrage definiert, die in Kombination mit einem Child-Listener den Client mit den Beiträgen des Nutzers aus dem Pfad in der Datenbank synchronisiert, basierend auf seiner Nutzer-ID und sortiert nach der Anzahl der Sterne, die jeder Beitrag erhalten hat. Diese Technik, IDs als Indexschlüssel zu verwenden, wird als „Data Fan-Out“ bezeichnet. Weitere Informationen dazu 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 Beiträge nach dem Wert des jeweiligen untergeordneten Elements "starCount" sortiert. Abfragen können auch nach verschachtelten untergeordneten Elementen sortiert werden, wenn Sie Daten haben, die 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. Dazu geben wir den relativen Pfad zum verschachtelten untergeordneten Element in unserem orderByChild()-Aufruf an.

Web

import { getDatabase, ref, query, orderByChild } from "firebase/database";

const db = getDatabase();
const mostViewedPosts = query(ref(db, 'posts'), orderByChild('metrics/views'));

Web

var mostViewedPosts = firebase.database().ref('posts').orderByChild('metrics/views');

Weitere Informationen zur Sortierung anderer Datentypen finden Sie unter Sortierung von Abfragedaten.

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 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 ausgewählter Sortiermethode.
startAfter() Gibt Elemente zurück, die größer als der angegebene Schlüssel oder Wert sind, je nach gewählter „order-by“-Methode.
endAt() Gibt Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind, je nach ausgewählter Sortiermethode.
endBefore() Gibt Elemente zurück, die kleiner als der angegebene Schlüssel oder Wert sind, je nach ausgewählter „order-by“-Methode.
equalTo() Gibt Elemente zurück, die dem angegebenen Schlüssel oder Wert entsprechen, je nach ausgewählter „order-by“-Methode.

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.

Anzahl der Ergebnisse begrenzen

Mit den Methoden limitToFirst() und limitToLast() können Sie eine maximale Anzahl von untergeordneten Elementen festlegen, die für ein bestimmtes Ereignis synchronisiert werden sollen. Wenn Sie beispielsweise mit limitToFirst() ein Limit von 100 festlegen, erhalten Sie anfangs nur bis zu 100 child_added-Ereignisse. Wenn Sie weniger als 100 Artikel in Ihrer Firebase-Datenbank gespeichert haben, wird für jeden Artikel ein child_added-Ereignis ausgelöst.

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

Im folgenden Beispiel wird gezeigt, wie in der Beispiel-Blogging-App eine Abfrage definiert wird, um eine Liste der 100 neuesten Beiträge aller Nutzer abzurufen:

Web

import { getDatabase, ref, query, limitToLast } from "firebase/database";

const db = getDatabase();
const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));

Web

var recentPostsRef = firebase.database().ref('posts').limitToLast(100);

In diesem Beispiel wird nur eine Abfrage definiert. Damit Daten tatsächlich synchronisiert werden, muss ein Listener angehängt werden.

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 Order-by-Methoden in der Klasse Query sortiert werden.

orderByChild

Wenn Sie orderByChild() verwenden, 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 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. 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 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 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.

  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 Kinder mit einem Stringwert als Schlüssel, die lexikografisch in aufsteigender Reihenfolge sortiert sind.

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.

Listener trennen

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

Sie können einen einzelnen Listener entfernen, indem Sie ihn als Parameter an off() übergeben. Wenn Sie off() für den Standort ohne Argumente aufrufen, werden alle Listener an diesem Standort 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