Cloud Firestore-Trigger

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 DocumentSnapshot -Oberfläche oder über das Admin SDK vornehmen.

In einem typischen Lebenszyklus führt eine Cloud Firestore-Funktion Folgendes aus:

  1. Wartet auf Änderungen an einem bestimmten Dokument.
  2. Löst aus, wenn ein Ereignis eintritt, und führt seine Aufgaben aus (Beispiele für Anwendungsfälle finden Sie unter Was kann ich mit Cloud Functions tun? ).
  3. Empfängt ein Datenobjekt, das eine Momentaufnahme der im angegebenen Dokument gespeicherten Daten enthält. Bei onWrite oder onUpdate Ereignissen enthält das Datenobjekt zwei Momentaufnahmen, 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 einer erheblichen Netzwerklatenz führen. Um die Leistung zu optimieren, sollten Sie ggf. den Ort der Funktion angeben.

Cloud Firestore-Funktionsauslöser

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 Abzug
onCreate Wird ausgelöst, wenn zum ersten Mal in ein Dokument geschrieben wird.
onUpdate Wird ausgelöst, wenn ein Dokument bereits vorhanden ist und irgendein 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.

Von Cloud Firestore ausgelöste Funktionen schreiben

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 ein Ereignis für jede Änderung an einem bestimmten Dokument 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, z. B. ein beliebiges 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 beliebiges Feld in einem beliebigen Dokument in users geändert wird, stimmt es mit einem Platzhalter namens userId .

Wenn ein Dokument in users Untersammlungen hat und ein Feld in einem der Dokumente dieser Untersammlungen geändert wird, wird der userId Platzhalter 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 jederzeit eine Funktion auslösen, wenn ein neues Dokument in einer Sammlung erstellt wird, indem Sie einen onCreate() 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 auslösen, wenn ein Dokument aktualisiert wird, indem Sie die Funktion onUpdate() mit einem Platzhalter verwenden. Diese Beispielfunktion ruft updateUser , 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 ...
    });

Auslösen einer Funktion, wenn ein Dokument gelöscht wird

Sie können auch eine Funktion auslösen, wenn ein Dokument gelöscht wird, indem Sie die Funktion onDelete() mit einem Platzhalter verwenden. Diese Beispielfunktion ruft deleteUser 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 alle Änderungen in einem Cloud Firestore-Dokument überwachen, indem Sie die Funktion onWrite() mit einem Platzhalter verwenden. Diese Beispielfunktion ruft modifyUser , 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 ...
    });

Lesen und Schreiben von Daten

Wenn eine Funktion ausgelöst wird, stellt sie eine Momentaufnahme der Daten bereit, die sich auf das Ereignis beziehen. Sie können diesen Snapshot zum Lesen oder Schreiben in das Dokument verwenden, das das Ereignis ausgelöst hat, oder das Firebase Admin SDK verwenden, um auf andere Teile Ihrer Datenbank zuzugreifen.

Ereignisdaten

Lesen von Daten

Wenn eine Funktion ausgelöst wird, möchten Sie möglicherweise Daten aus einem Dokument abrufen, das aktualisiert wurde, oder die Daten vor der Aktualisierung abrufen. Sie können die vorherigen Daten abrufen, indem 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');

Schreiben von Daten

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 Snapshots zugreifen, der an Ihre Funktion zurückgegeben wird.

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, einfach ä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 geliefert, aber ein einzelnes Ereignis kann zu mehreren Funktionsaufrufen führen. Vermeiden Sie die Abhängigkeit von genau einmaligen Mechanismen und schreiben Sie idempotente Funktionen .
  • Cloud Firestore-Trigger für Cloud Functions sind nur für Cloud Firestore im nativen Modus verfügbar . Es ist für Cloud Firestore im Datastore-Modus nicht verfügbar.