Daten speichern

Möglichkeiten zum Speichern von Daten

SETZEN Schreiben oder ersetzen Sie Daten in einen definierten Pfad , z. B. fireblog/users/user1/<data>
PATCH Aktualisieren Sie einige Schlüssel für einen definierten Pfad, ohne alle Daten zu ersetzen.
POST Zu einer Datenliste in unserer 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 Blogging-Anwendung mit Beiträgen und Benutzern. Alle Daten für unsere Anwendung werden unter dem Pfad „fireblog“ unter der Firebase-Datenbank-URL „https://docs-examples.firebaseio.com/fireblog“ gespeichert.

Beginnen wir damit, einige Benutzerdaten in unserer Firebase-Datenbank zu speichern. Wir speichern jeden Benutzer mit einem eindeutigen Benutzernamen sowie seinen vollständigen Namen und sein Geburtsdatum. Da jeder Benutzer einen eindeutigen Benutzernamen hat, ist es sinnvoll, hier PUT anstelle von POST zu verwenden, da wir bereits über den Schlüssel verfügen 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 ihm 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 verschachtelt den 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 dieser Werte 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 HTTP-Statuscode 200 OK angezeigt und die Antwort enthält die Daten, die wir in die Datenbank geschrieben haben. Das erste Beispiel löst nur ein Ereignis auf Clients aus, die die Daten überwachen, während das zweite Beispiel zwei auslöst. Es ist wichtig zu beachten, dass der erste Ansatz diese überschreiben würde, wenn bereits Daten im Benutzerpfad vorhanden wären, die zweite Methode jedoch nur den Wert jedes einzelnen untergeordneten Knotens ändern würde, während andere untergeordnete Knoten unverändert bleiben würden. PUT entspricht set() in unserem JavaScript SDK.

Aktualisieren von Daten mit PATCH

Mithilfe einer PATCH Anfrage können wir bestimmte untergeordnete Elemente an einem Standort aktualisieren, ohne vorhandene Daten zu überschreiben. Fügen wir Turings Spitznamen mit einer PATCH Anfrage zu seinen Benutzerdaten hinzu:

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

Die obige Anfrage schreibt nickname in unser alanisawesome Objekt, ohne den name oder birthday zu löschen. Beachten Sie, dass name und birthday gelöscht worden wären, wenn wir hier stattdessen eine PUT Anfrage gestellt hätten, da sie nicht in der Anfrage enthalten waren. Die Daten in unserer Firebase-Datenbank sehen nun so aus:

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

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

Firebase unterstützt auch Multipfad-Updates. Das bedeutet, dass PATCH jetzt Werte an mehreren Stellen in Ihrer Firebase-Datenbank gleichzeitig aktualisieren kann, eine leistungsstarke Funktion, die Ihnen bei der Denormalisierung Ihrer Daten hilft. Mithilfe von Multipfad-Updates können wir sowohl Alan als auch 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 diesem Update wurden sowohl Alan als auch Grace ihre Spitznamen hinzugefügt:

{
  "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"
    }
  }
}

Beachten Sie, dass der Versuch, Objekte durch Schreiben von Objekten mit den enthaltenen Pfaden zu aktualisieren, zu einem unterschiedlichen Verhalten führt. Schauen wir uns an, was passiert, wenn wir stattdessen versuchen, Grace und Alan auf diese Weise zu 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 unterschiedlichen Verhalten, nämlich dem Überschreiben des gesamten /fireblog/users Knotens:

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

Aktualisieren von Daten mit bedingten Anforderungen

Sie können bedingte Anforderungen verwenden, das REST-Äquivalent zu Transaktionen, um Daten entsprechend ihrem aktuellen Status zu aktualisieren. Wenn Sie beispielsweise einen Upvote-Zähler erhöhen und sicherstellen möchten, dass die Anzahl mehrere gleichzeitige Upvotes 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 die gleiche Zahl ändern, schlägt eine der Schreibanforderungen fehl und Sie können die Anforderung dann mit dem neuen Wert erneut versuchen.
  1. Um eine bedingte Anfrage an einem Standort durchzuführen, rufen Sie den eindeutigen Bezeichner für die aktuellen Daten an diesem Standort oder den ETag ab. Wenn sich die Daten an diesem Ort ändern, ändert sich auch das ETag. Sie können ein ETag mit jeder anderen Methode als PATCH anfordern. Das folgende Beispiel verwendet eine GET Anfrage.
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    Durch den gezielten Aufruf des ETags im Header wird das 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 das zurückgegebene ETag in Ihre nächste PUT oder DELETE Anfrage ein, um Daten zu aktualisieren, die speziell mit diesem ETag-Wert übereinstimmen. Um unserem Beispiel zu folgen, verwenden Sie den folgenden Code, um den Zähler auf 11 oder 1 größer als den ursprünglich abgerufenen Wert von 10 zu aktualisieren und die Anforderung fehlzuschlagen, wenn der Wert nicht mehr übereinstimmt:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    Wenn der Wert der Daten dem angegebenen Wert entspricht Der Standort ist immer noch 10, das ETag in der PUT Anfrage stimmt überein und die Anfrage ist erfolgreich und schreibt 11 in die Datenbank.
    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 Benutzer einen neuen Wert in die Datenbank schreibt, schlägt die Anfrage fehl, ohne dass an den Speicherort geschrieben wird. Die Rückantwort enthält den neuen Wert und 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 erneut versuchen möchten. Die Echtzeitdatenbank wiederholt fehlgeschlagene bedingte Anforderungen nicht automatisch. Sie können jedoch den neuen Wert und das ETag verwenden, um eine neue bedingte Anfrage mit den von der Fehlerantwort zurückgegebenen Informationen zu erstellen.

REST-basierte bedingte Anforderungen implementieren den HTTP- IF-Match- Standard. 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 vorschlägt, dass ETags bei allen Anfragen zurückgegeben werden, gibt Realtime Database nur ETags bei Anfragen zurück, die den X-Firebase-ETag -Header enthalten. Dies reduziert die Abrechnungskosten für Standardanfragen.

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

Speichern von Datenlisten

Um einen eindeutigen, zeitstempelbasierten Schlüssel für jedes zu einer Firebase-Datenbankreferenz hinzugefügte untergeordnete Element zu generieren, können wir eine POST Anfrage senden. Für unseren users war es sinnvoll, unsere eigenen Schlüssel zu definieren, da jeder Benutzer einen eindeutigen Benutzernamen hat. Wenn Benutzer jedoch Blog-Beiträge zur App hinzufügen, verwenden wir eine POST Anfrage, um automatisch einen Schlüssel für jeden Blog-Beitrag 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"
    }
  }
}

Beachten Sie, dass der Schlüssel -JSOpn9ZC54A4P4RoqVa automatisch für uns generiert wurde, weil wir eine POST Anfrage verwendet haben. Eine erfolgreiche Anfrage wird durch den HTTP-Statuscode 200 OK angezeigt und die Antwort enthält den Schlüssel der neu hinzugefügten Daten:

{"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. Folgendes würde Alan aus unserem users löschen:

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 beim Schreiben von Daten in die Datenbank die folgenden URI-Parameter:

Autor

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

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

drucken

Mit dem print können wir das Format unserer Antwort aus der Datenbank angeben. Durch das Hinzufügen print=pretty zu unserer Anfrage 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.

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

Serverwerte schreiben

Serverwerte können an einem Ort mithilfe eines Platzhalterwerts geschrieben werden, bei dem es sich um ein Objekt mit einem einzelnen ".sv" -Schlüssel handelt. Der Wert für diesen Schlüssel ist der Typ des Serverwerts, den wir festlegen möchten. Um beispielsweise einen Zeitstempel festzulegen, wenn ein Benutzer erstellt wird, könnten 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.

Verbesserung der Schreibleistung

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

In Fällen, in denen wir viele Anfragen an die Datenbank stellen, können wir die HTTPS-Verbindung wiederverwenden, indem wir eine Keep-Alive Anfrage im HTTP-Header senden.

Fehlerbedingungen

Unter folgenden Umständen gibt die REST-API Fehlercodes zurück:

HTTP-Statuscodes
400 Ungültige Anfrage

Eine der folgenden Fehlerbedingungen:

  • PUT oder POST Daten können nicht analysiert werden.
  • Fehlende PUT oder POST Daten.
  • Die Anfrage versucht, zu große Daten PUT oder POST zu senden.
  • Der REST-API-Aufruf enthält ungültige untergeordnete Namen als Teil des Pfads.
  • Der REST-API-Aufrufpfad 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 flachen 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 access_token ist fehlgeschlagen.
  • Die Anfrage verstößt gegen Ihre Firebase-Echtzeitdatenbank-Sicherheitsregeln.
404 Nicht gefunden Die angegebene Firebase-Datenbank wurde nicht gefunden.
500 Interner Serverfehler Der Server hat einen Fehler zurückgegeben. Weitere Einzelheiten finden Sie in der Fehlermeldung.
503 Dienst nicht verfügbar Die angegebene Firebase-Echtzeitdatenbank ist vorübergehend nicht verfügbar, was bedeutet, dass die Anfrage nicht versucht wurde.

Daten sichern

Firebase verfügt über eine Sicherheitssprache, mit der wir definieren können, welche Benutzer Lese- und Schreibzugriff auf verschiedene Knoten unserer Daten haben. Weitere Informationen hierzu finden Sie unter Sicherheitsregeln für Echtzeitdatenbanken .

Nachdem wir uns nun mit dem Speichern von Daten befasst haben, können wir im nächsten Abschnitt lernen, wie wir unsere Daten über die REST-API aus der Firebase-Datenbank abrufen.