Mit Cloud Functions können Sie Ereignisse in Cloud Firestore verarbeiten, ohne den Clientcode aktualisieren zu müssen. Sie können Cloud Firestore-Änderungen über die Dokument-Snapshot-Schnittstelle oder über das Admin SDK vornehmen.
In einem typischen Lebenszyklus führt eine Cloud Firestore-Funktion Folgendes aus:
- Wartet auf Änderungen an einem bestimmten Dokument.
- Wird ausgelöst, wenn ein Ereignis eintritt, und führt seine Aufgaben aus.
- Empfängt ein Datenobjekt, das eine Momentaufnahme der im angegebenen Dokument gespeicherten Daten enthält. Bei Schreib- oder Aktualisierungsereignissen enthält das Datenobjekt zwei Snapshots, die den Datenzustand vor und nach dem auslösenden Ereignis darstellen.
Die Entfernung zwischen dem Standort der Firestore-Instanz und dem Standort der Funktion kann zu erheblicher Netzwerklatenz führen. Um die Leistung zu optimieren, sollten Sie ggf. den Speicherort der Funktion angeben.
Auslöser der Cloud Firestore-Funktion
Das Cloud Functions for Firebase SDK exportiert ein functions.firestore
-Objekt, mit dem Sie Handler erstellen können, die an bestimmte Cloud Firestore-Ereignisse gebunden sind.
Ereignistyp | Auslösen |
---|---|
onCreate | Wird ausgelöst, wenn ein Dokument zum ersten Mal beschrieben wird. |
onUpdate | Wird ausgelöst, wenn ein Dokument bereits vorhanden ist und ein Wert geändert wurde. |
onDelete | Wird ausgelöst, wenn ein Dokument mit Daten gelöscht wird. |
onWrite | Wird ausgelöst, wenn onCreate , onUpdate oder onDelete ausgelöst wird. |
Wenn Sie noch kein Projekt für Cloud Functions for Firebase aktiviert haben, lesen Sie „Erste Schritte: Schreiben und Bereitstellen Ihrer ersten Funktionen“, um Ihr Cloud Functions for Firebase-Projekt zu konfigurieren und einzurichten.
Schreiben von durch Cloud Firestore ausgelösten Funktionen
Definieren Sie einen Funktionsauslöser
Um einen Cloud Firestore-Trigger zu definieren, geben Sie einen Dokumentpfad und einen Ereignistyp an:
Node.js
const functions = require('firebase-functions');
exports.myFunction = functions.firestore
.document('my-collection/{docId}')
.onWrite((change, context) => { /* ... */ });
Dokumentpfade können entweder auf ein bestimmtes Dokument oder auf ein Platzhaltermuster verweisen.
Geben Sie ein einzelnes Dokument an
Wenn Sie bei einer Änderung an einem bestimmten Dokument ein Ereignis auslösen möchten, können Sie die folgende Funktion verwenden.
Node.js
// Listen for any change on document `marie` in collection `users` exports.myFunctionName = functions.firestore .document('users/marie').onWrite((change, context) => { // ... Your code here });
Geben Sie eine Gruppe von Dokumenten mit Platzhaltern an
Wenn Sie einen Auslöser an eine Gruppe von Dokumenten anhängen möchten, beispielsweise an ein Dokument in einer bestimmten Sammlung, verwenden Sie anstelle der Dokument-ID einen {wildcard}
:
Node.js
// Listen for changes in all documents in the 'users' collection exports.useWildcard = functions.firestore .document('users/{userId}') .onWrite((change, context) => { // If we set `/users/marie` to {name: "Marie"} then // context.params.userId == "marie" // ... and ... // change.after.data() == {name: "Marie"} });
Wenn in diesem Beispiel ein Feld in einem beliebigen Dokument in „ users
geändert wird, entspricht es einem Platzhalter namens userId
.
Wenn ein Dokument in users
“ über Untersammlungen verfügt und ein Feld in einem dieser Untersammlungsdokumente geändert wird, wird der Platzhalter „ userId
nicht ausgelöst.
Platzhalterübereinstimmungen werden aus dem Dokumentpfad extrahiert und in context.params
gespeichert. Sie können beliebig viele Platzhalter definieren, um explizite Sammlungs- oder Dokument-IDs zu ersetzen, zum Beispiel:
Node.js
// Listen for changes in all documents in the 'users' collection and all subcollections exports.useMultipleWildcards = functions.firestore .document('users/{userId}/{messageCollectionId}/{messageId}') .onWrite((change, context) => { // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then // context.params.userId == "marie"; // context.params.messageCollectionId == "incoming_messages"; // context.params.messageId == "134"; // ... and ... // change.after.data() == {body: "Hello"} });
Ereignisauslöser
Lösen Sie eine Funktion aus, wenn ein neues Dokument erstellt wird
Sie können eine Funktion jedes Mal auslösen, wenn ein neues Dokument in einer Sammlung erstellt wird, indem Sie einen onCreate()
Handler mit einem Platzhalter verwenden. Diese Beispielfunktion ruft createUser
jedes Mal auf, wenn ein neues Benutzerprofil hinzugefügt wird:
Node.js
exports.createUser = functions.firestore .document('users/{userId}') .onCreate((snap, context) => { // Get an object representing the document // e.g. {'name': 'Marie', 'age': 66} const newValue = snap.data(); // access a particular field as you would any JS property const name = newValue.name; // perform desired operations ... });
Lösen Sie eine Funktion aus, wenn ein Dokument aktualisiert wird
Sie können auch eine Funktion zum Auslösen auslösen, wenn ein Dokument aktualisiert wird, indem Sie die Funktion onUpdate()
mit einem Platzhalter verwenden. Diese Beispielfunktion ruft updateUser
auf, wenn ein Benutzer sein Profil ändert:
Node.js
exports.updateUser = functions.firestore .document('users/{userId}') .onUpdate((change, context) => { // Get an object representing the document // e.g. {'name': 'Marie', 'age': 66} const newValue = change.after.data(); // ...or the previous value before this update const previousValue = change.before.data(); // access a particular field as you would any JS property const name = newValue.name; // perform desired operations ... });
Lösen Sie eine Funktion aus, wenn ein Dokument gelöscht wird
Sie können eine Funktion auch auslösen, wenn ein Dokument gelöscht wird, indem Sie die Funktion onDelete()
mit einem Platzhalter verwenden. Diese Beispielfunktion ruft deleteUser
auf, wenn ein Benutzer sein Benutzerprofil löscht:
Node.js
exports.deleteUser = functions.firestore .document('users/{userID}') .onDelete((snap, context) => { // Get an object representing the document prior to deletion // e.g. {'name': 'Marie', 'age': 66} const deletedValue = snap.data(); // perform desired operations ... });
Lösen Sie eine Funktion für alle Änderungen an einem Dokument aus
Wenn Ihnen die Art des ausgelösten Ereignisses egal ist, können Sie mithilfe der Funktion onWrite()
mit einem Platzhalter auf alle Änderungen in einem Cloud Firestore-Dokument warten. Diese Beispielfunktion ruft modifyUser
auf, wenn ein Benutzer erstellt, aktualisiert oder gelöscht wird:
Node.js
exports.modifyUser = functions.firestore .document('users/{userID}') .onWrite((change, context) => { // Get an object with the current document value. // If the document does not exist, it has been deleted. const document = change.after.exists ? change.after.data() : null; // Get an object with the previous document value (for update or delete) const oldDocument = change.before.data(); // perform desired operations ... });
Daten lesen und schreiben
Wenn eine Funktion ausgelöst wird, stellt sie eine Momentaufnahme der mit dem Ereignis verbundenen Daten bereit. Sie können diesen Snapshot verwenden, um aus dem Dokument zu lesen oder in das Dokument zu schreiben, das das Ereignis ausgelöst hat, oder das Firebase Admin SDK verwenden, um auf andere Teile Ihrer Datenbank zuzugreifen.
Ereignisdaten
Daten lesen
Wenn eine Funktion ausgelöst wird, möchten Sie möglicherweise Daten aus einem aktualisierten Dokument abrufen oder die Daten vor der Aktualisierung abrufen. Sie können die vorherigen Daten abrufen, indem Sie change.before.data()
verwenden, das den Dokument-Snapshot vor der Aktualisierung enthält. In ähnlicher Weise enthält change.after.data()
den Dokument-Snapshot-Status nach der Aktualisierung.
Node.js
exports.updateUser2 = functions.firestore .document('users/{userId}') .onUpdate((change, context) => { // Get an object representing the current document const newValue = change.after.data(); // ...or the previous value before this update const previousValue = change.before.data(); });
Sie können wie bei jedem anderen Objekt auf Eigenschaften zugreifen. Alternativ können Sie die get
Funktion verwenden, um auf bestimmte Felder zuzugreifen:
Node.js
// Fetch data using standard accessors const age = snap.data().age; const name = snap.data()['name']; // Fetch data using built in accessor const experience = snap.get('experience');
Daten schreiben
Jeder Funktionsaufruf ist einem bestimmten Dokument in Ihrer Cloud Firestore-Datenbank zugeordnet. Sie können auf dieses Dokument als DocumentReference
in der ref
Eigenschaft des an Ihre Funktion zurückgegebenen Snapshots zugreifen.
Diese DocumentReference
stammt aus dem Cloud Firestore Node.js SDK und enthält Methoden wie update()
, set()
und remove()
, sodass Sie das Dokument, das die Funktion ausgelöst hat, problemlos ändern können.
Node.js
// Listen for updates to any `user` document. exports.countNameChanges = functions.firestore .document('users/{userId}') .onUpdate((change, context) => { // Retrieve the current and previous value const data = change.after.data(); const previousData = change.before.data(); // We'll only update if the name has changed. // This is crucial to prevent infinite loops. if (data.name == previousData.name) { return null; } // Retrieve the current count of name changes let count = data.name_change_count; if (!count) { count = 0; } // Then return a promise of a set operation to update the count return change.after.ref.set({ name_change_count: count + 1 }, {merge: true}); });
Daten außerhalb des Triggerereignisses
Cloud Functions werden in einer vertrauenswürdigen Umgebung ausgeführt, was bedeutet, dass sie als Dienstkonto für Ihr Projekt autorisiert sind. Sie können Lese- und Schreibvorgänge mit dem Firebase Admin SDK durchführen:
Node.js
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.writeToFirestore = functions.firestore
.document('some/doc')
.onWrite((change, context) => {
db.doc('some/otherdoc').set({ ... });
});
Einschränkungen
Beachten Sie die folgenden Einschränkungen für Cloud Firestore-Trigger für Cloud Functions:
- Die Bestellung ist nicht garantiert. Schnelle Änderungen können Funktionsaufrufe in einer unerwarteten Reihenfolge auslösen.
- Ereignisse werden mindestens einmal übermittelt, ein einzelnes Ereignis kann jedoch zu mehreren Funktionsaufrufen führen. Vermeiden Sie die Abhängigkeit von der genau-einmaligen Mechanik und schreiben Sie idempotente Funktionen .
- Cloud Firestore im Datastore-Modus erfordert Cloud Functions (2. Generation). Cloud Functions (1. Generation) unterstützt den Datastore-Modus nicht.
- Cloud Functions (1. Generation) funktioniert nur mit der Datenbank „(Standard)“ und unterstützt keine benannten Cloud Firestore-Datenbanken. Bitte verwenden Sie Cloud Functions (2. Generation), um Ereignisse für benannte Datenbanken zu konfigurieren.