Daten speichern

Möglichkeiten zum Speichern von Daten

PUT Daten in einen definierten Pfad schreiben oder ersetzen, z. B. fireblog/users/user1/<data>
PATCH Einige der Schlüssel für einen definierten Pfad aktualisieren, ohne alle Daten zu ersetzen.
POST Daten einer Liste in der Firebase-Datenbank hinzufügen. Jedes Mal, wenn wir eine POST Anfrage senden, generiert der Firebase-Client einen eindeutigen Schlüssel, z. B. fireblog/users/<unique-id>/<data>
LÖSCHEN Daten aus der angegebenen Firebase-Datenbankreferenz entfernen.

Daten mit PUT schreiben

Der grundlegende Schreibvorgang über die REST API ist PUT. Um das Speichern von Daten zu demonstrieren, erstellen wir eine Bloganwendung mit Beiträgen und Nutzern. Alle Daten für unsere Anwendung werden unter dem Pfad `fireblog` in der Firebase-Datenbank-URL `https://docs-examples.firebaseio.com/fireblog` gespeichert.

Speichern wir zuerst einige Nutzerdaten in unserer Firebase-Datenbank. Wir speichern jeden Nutzer mit einem eindeutigen Nutzernamen sowie mit seinem vollständigen Namen und Geburtsdatum. Da jeder Nutzer einen eindeutigen Nutzernamen hat, ist es sinnvoll, hier PUT anstelle von POST zu verwenden, da wir den Schlüssel bereits haben und keinen erstellen müssen.

Mit PUT können wir einen String, eine Zahl, einen booleschen Wert, ein Array oder ein beliebiges JSON-Objekt in unsere Firebase-Datenbank schreiben. In diesem Fall übergeben wir ein Objekt:

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'

Wenn ein JSON-Objekt in der Datenbank gespeichert wird, werden die Objekteigenschaften automatisch auf verschachtelte Weise untergeordneten Speicherorten zugeordnet. Wenn wir zum neu erstellten Knoten navigieren, sehen wir den Wert „Alan Turing“. Wir können Daten auch direkt an einem untergeordneten Speicherort speichern:

curl -X PUT -d '"Alan Turing"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'

Die beiden oben genannten Beispiele – das Schreiben des Werts gleichzeitig mit einem Objekt und das separate Schreiben an untergeordnete Speicherorte – führen dazu, dass dieselben Daten in unserer Firebase-Datenbank gespeichert werden:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

Eine erfolgreiche Anfrage wird durch den 200 OK HTTP-Statuscode angezeigt. Die Antwort enthält die Daten, die wir in die Datenbank geschrieben haben. Das erste Beispiel löst nur ein Ereignis bei Clients aus, die die Daten beobachten, während das zweite Beispiel zwei Ereignisse auslöst. Wenn bereits Daten im Nutzerpfad vorhanden waren, werden sie beim ersten Ansatz überschrieben. Bei der zweiten Methode wird jedoch nur der Wert jedes einzelnen untergeordneten Knotens geändert, während andere untergeordnete Knoten unverändert bleiben. PUT entspricht set() in unserem JavaScript SDK.

Daten mit PATCH aktualisieren

Mit einer PATCH Anfrage können wir bestimmte untergeordnete Elemente an einem Speicherort aktualisieren, ohne vorhandene Daten zu überschreiben. Fügen wir den Spitznamen von Turing mit einer PATCH Anfrage zu seinen Nutzerdaten hinzu:

curl -X PATCH -d '{
  "nickname": "Alan The Machine"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

Mit der oben genannten Anfrage wird nickname in unser alanisawesome-Objekt geschrieben, ohne die untergeordneten Elemente name oder birthday zu löschen. Wenn wir stattdessen eine PUT Anfrage gesendet hätten, wären name und birthday gelöscht worden, da sie nicht in der Anfrage enthalten waren. Die Daten in unserer Firebase Datenbank sehen jetzt so aus:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    }
  }
}

Eine erfolgreiche Anfrage wird durch den 200 OK HTTP-Statuscode angezeigt. Die Antwort enthält die aktualisierten Daten, die in die Datenbank geschrieben wurden.

Firebase unterstützt auch Aktualisierungen mit mehreren Pfaden. Das bedeutet, dass PATCH jetzt Werte an mehreren Speicherorten in Ihrer Firebase-Datenbank gleichzeitig aktualisieren kann. Dies ist eine leistungsstarke Funktion, mit der Sie Ihre Daten denormalisieren können. Mit Aktualisierungen mit mehreren Pfaden können wir Alan und Grace gleichzeitig Spitznamen hinzufügen:

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Nach dieser Aktualisierung haben sowohl Alan als auch Grace Spitznamen:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "date_of_birth": "December 9, 1906",
      "full_name": "Grace Hopper",
      "nickname": "Amazing Grace"
    }
  }
}

Wenn Sie versuchen, Objekte zu aktualisieren, indem Sie Objekte mit den Pfaden schreiben, führt dies zu einem anderen Verhalten. Sehen wir uns an, was passiert, wenn wir Grace und Alan stattdessen auf diese Weise aktualisieren:

curl -X PATCH -d '{
  "alanisawesome": {"nickname": "Alan The Machine"},
  "gracehopper": {"nickname": "Amazing Grace"}
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Dies führt zu einem anderen Verhalten, nämlich zum Überschreiben des gesamten Knotens /fireblog/users:

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

Daten mit bedingten Anfragen aktualisieren

Sie können bedingte Anfragen verwenden, die dem REST-Äquivalent von Transaktionen entsprechen, um Daten entsprechend ihrem aktuellen Status zu aktualisieren. Wenn Sie beispielsweise einen Zähler für positive Bewertungen erhöhen und sicherstellen möchten, dass die Anzahl mehrere gleichzeitige positive Bewertungen genau widerspiegelt, verwenden Sie eine bedingte Anfrage, um den neuen Wert in den Zähler zu schreiben. Anstelle von zwei Schreibvorgängen, die den Zähler auf dieselbe Zahl ändern, schlägt eine der Schreibanfragen fehl. Sie können die Anfrage dann mit dem neuen Wert wiederholen.
  1. Um eine bedingte Anfrage an einem Speicherort auszuführen, rufen Sie die eindeutige Kennung für die aktuellen Daten an diesem Speicherort ab, also den ETag. Wenn sich die Daten an diesem Speicherort ändern, ändert sich auch der ETag. Sie können einen ETag mit jeder Methode außer PATCH anfordern. Im folgenden Beispiel wird eine GET-Anfrage verwendet.
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    Wenn Sie den ETag im Header aufrufen, wird der ETag des angegebenen Speicherorts in der HTTP-Antwort zurückgegeben.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    10 // Current value of the data at the specified location
  2. Fügen Sie den zurückgegebenen ETag in Ihre nächste PUT oder DELETE Anfrage ein, um Daten zu aktualisieren, die genau diesem ETag-Wert entsprechen. Um den Zähler auf 11 zu aktualisieren, also um 1 höher als der ursprünglich abgerufene Wert von 10, und die Anfrage abzulehnen, wenn der Wert nicht mehr übereinstimmt, verwenden Sie den folgenden Code:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    Wenn der Wert der Daten am angegebenen Speicherort immer noch 10 ist, stimmt der ETag in der PUT-Anfrage überein und die Anfrage ist erfolgreich. Der Wert 11 wird in die Datenbank geschrieben.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    Cache-Control: no-cache
    
    11 // New value of the data at the specified location, written by the conditional request
    Wenn der Speicherort nicht mehr mit dem ETag übereinstimmt, was passieren kann, wenn ein anderer Nutzer einen neuen Wert in die Datenbank geschrieben hat, schlägt die Anfrage fehl, ohne dass etwas an den Speicherort geschrieben wird. Die Antwort enthält den neuen Wert und den ETag.
    HTTP/1.1 412 Precondition Failed
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    12 // New value of the data at the specified location
  3. Verwenden Sie die neuen Informationen, wenn Sie die Anfrage wiederholen möchten. Realtime Database wiederholt fehlgeschlagene bedingte Anfragen nicht automatisch. Sie können jedoch den neuen Wert und den ETag verwenden, um eine neue bedingte Anfrage mit den Informationen zu erstellen, die in der Antwort bei einem Fehler zurückgegeben wurden.

Bei REST-basierten bedingten Anfragen wird der HTTP Standard „if-match“ implementiert. Sie unterscheiden sich jedoch in folgenden Punkten vom Standard:

  • Sie können für jede „if-match“-Anfrage nur einen ETag-Wert angeben, nicht mehrere.
  • Während der Standard vorschreibt, dass ETags mit allen Anfragen zurückgegeben werden, gibt Realtime Database ETags nur mit Anfragen zurück, die den X-Firebase-ETag Header enthalten. Dadurch werden die Abrechnungskosten für Standardanfragen gesenkt.

Bedingte Anfragen können auch langsamer sein als typische REST-Anfragen.

Listen mit Daten speichern

Um einen eindeutigen, zeitstempelbasierten Schlüssel für jedes untergeordnete Element zu generieren, das einer Firebase-Datenbankreferenz hinzugefügt wird können wir eine POST Anfrage senden. Für unseren users-Pfad war es sinnvoll, eigene Schlüssel zu definieren, da jeder Nutzer einen eindeutigen Nutzernamen hat. Wenn Nutzer jedoch Blogbeiträge zur App hinzufügen, verwenden wir eine POST Anfrage, um automatisch einen Schlüssel für jeden Blogbeitrag zu generieren:

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

Unser posts-Pfad enthält jetzt die folgenden Daten:

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

Der Schlüssel -JSOpn9ZC54A4P4RoqVa wurde automatisch für uns generiert, da wir eine POST Anfrage verwendet haben. Eine erfolgreiche Anfrage wird durch den 200 OK HTTP-Statuscode angezeigt. Die Antwort enthält den Schlüssel der neuen Daten, die hinzugefügt wurden:

{"name":"-JSOpn9ZC54A4P4RoqVa"}

Daten entfernen

Um Daten aus der Datenbank zu entfernen, können wir eine DELETE Anfrage mit der URL des Pfads senden, aus dem wir Daten löschen möchten. Mit dem folgenden Befehl wird Alan aus unserem users Pfad gelöscht:

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

Eine erfolgreiche DELETE-Anfrage wird durch den HTTP-Statuscode 200 OK mit einer Antwort angezeigt, die JSON null enthält.

URI-Parameter

Die REST API akzeptiert die folgenden URI-Parameter, wenn Daten in die Datenbank geschrieben werden:

auth

Der Anfrageparameter auth ermöglicht den Zugriff auf Daten, die durch Firebase Realtime Database Security Rules geschützt sind, und wird von allen Anfragetypen unterstützt. Das Argument kann entweder unser Firebase-App-Secret oder ein Authentifizierungstoken sein, das wir im Abschnitt zur Nutzerautorisierung behandeln. Im folgenden Beispiel senden wir eine POST Anfrage mit einem auth Parameter, wobei CREDENTIAL entweder unser Firebase-App-Secret oder ein Authentifizierungstoken ist:

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

ausgeben

Mit dem print Parameter können wir das Format unserer Antwort aus der Datenbank angeben. Wenn wir unserer Anfrage print=pretty hinzufügen, werden die Daten in einem für Menschen lesbaren Format zurückgegeben. print=pretty wird von GET, PUT, POST, PATCH, und DELETE Anfragen unterstützt.

Wenn wir die Ausgabe vom Server beim Schreiben von Daten unterdrücken möchten, können wir unserer Anfrage print=silent hinzufügen. Die resultierende Antwort ist leer und wird durch den 204 No Content HTTP-Statuscode angezeigt, wenn die Anfrage erfolgreich ist. Der print=silent wird von GET, PUT, POST- und PATCH-Anfragen unterstützt.

Serverwerte schreiben

Serverwerte können an einem Speicherort mit einem Platzhalterwert geschrieben werden. Dieser ist ein Objekt mit einem einzelnen ".sv" Schlüssel. Der Wert für diesen Schlüssel ist der Typ des Serverwerts, den wir festlegen möchten. Wenn wir beispielsweise einen Zeitstempel festlegen möchten, wenn ein Nutzer erstellt wird, können wir Folgendes tun:

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp" ist der einzige unterstützte Serverwert und gibt die Zeit seit der UNIX Epoche in Millisekunden an.

Schreibgeschwindigkeit verbessern

Wenn wir große Datenmengen in die Datenbank schreiben, können wir den print=silent Parameter verwenden, um die Schreibgeschwindigkeit zu verbessern und die Bandbreitennutzung zu verringern. Beim normalen Schreibvorgang antwortet der Server mit den geschriebenen JSON-Daten. Wenn print=silent angegeben ist, schließt der Server die Verbindung sofort nachdem die Daten empfangen wurden, wodurch die Bandbreitennutzung reduziert wird.

Wenn wir viele Anfragen an die Datenbank senden, können wir die HTTPS Verbindung wiederverwenden, indem wir eine Keep-Alive Anfrage im HTTP-Header senden.

Fehlerbedingungen

Die REST API gibt unter folgenden Umständen Fehlercodes zurück:

HTTP-Statuscodes
400 Ungültige Anfrage

Eine der folgenden Fehlerbedingungen:

  • PUT- oder POST-Daten können nicht geparst werden.
  • PUT- oder POST-Daten fehlen.
  • Die Anfrage versucht, zu große PUT- oder POST-Daten zu senden, die zu groß sind.
  • Der REST API-Aufruf enthält ungültige untergeordnete Namen als Teil des Pfads.
  • Der Pfad des REST API-Aufrufs ist zu lang.
  • Die Anfrage enthält einen unbekannten Serverwert.
  • Der Index für die Abfrage ist nicht in Ihren Firebase Realtime Database Security Rules definiert.
  • Die Anfrage unterstützt einen der angegebenen Abfrageparameter nicht.
  • Die Anfrage mischt Abfrageparameter mit einer oberflächlichen GET-Anfrage.
401 Nicht autorisiert

Eine der folgenden Fehlerbedingungen:

  • Das Authentifizierungstoken ist abgelaufen.
  • Das in der Anfrage verwendete Authentifizierungstoken ist ungültig.
  • Die Authentifizierung mit einem Zugriffstoken ist fehlgeschlagen.
  • Die Anfrage verstößt gegen Ihre Firebase Realtime Database Security Rules.
404 Nicht gefunden Die angegebene Firebase-Datenbank wurde nicht gefunden.
500 Interner Serverfehler Der Server hat einen Fehler zurückgegeben. Weitere Informationen finden Sie in der Fehlermeldung.
503 Dienst nicht verfügbar Die angegebene Firebase Realtime Database ist vorübergehend nicht verfügbar. Die Anfrage wurde daher nicht versucht.

Daten sichern

Firebase hat eine Sicherheitssprache, mit der wir definieren können, welche Nutzer Lese- und Schreibzugriff auf verschiedene Knoten unserer Daten haben. Weitere Informationen finden Sie unter Realtime Database Security Rules.

Nachdem wir nun das Speichern von Daten behandelt haben, erfahren Sie im nächsten Abschnitt, wie Sie unsere Daten über die REST API aus der Firebase Datenbank abrufen.