Google is committed to advancing racial equity for Black communities. See how.
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Datenbank-Trigger

Mit Cloud-Funktionen können Sie Ereignisse in der Firebase-Echtzeitdatenbank verarbeiten, ohne den Clientcode aktualisieren zu müssen. Mit Cloud-Funktionen können Sie Echtzeitdatenbankvorgänge mit vollständigen Administratorrechten ausführen und sicherstellen, dass jede Änderung an der Echtzeitdatenbank einzeln verarbeitet wird. Sie können Änderungen an der Firebase-Echtzeitdatenbank über den DataSnapshot oder über das Admin-SDK vornehmen.

In einem typischen Lebenszyklus führt eine Firebase-Echtzeitdatenbankfunktion Folgendes aus:

  1. Wartet auf Änderungen an einem bestimmten Speicherort der Echtzeitdatenbank.
  2. Wird ausgelöst, wenn ein Ereignis auftritt und seine Aufgaben ausführt (Beispiele für Anwendungsfälle finden Sie unter Was kann ich mit Cloud-Funktionen tun? ).
  3. Empfängt ein Datenobjekt, das eine Momentaufnahme der im angegebenen Dokument gespeicherten Daten enthält.

Lösen Sie eine Echtzeit-Datenbankfunktion aus

Erstellen Sie mit functions.database neue Funktionen für Echtzeitdatenbankereignisse. Um zu steuern, wann die Funktion ausgelöst wird, geben Sie einen der Ereignishandler an und geben Sie den Pfad der Echtzeitdatenbank an, in dem auf Ereignisse gewartet wird.

Legen Sie den Ereignishandler fest

Mit Funktionen können Sie Echtzeitdatenbankereignisse auf zwei Spezifitätsebenen verarbeiten. Sie können nur auf Erstellungs-, Aktualisierungs- oder Löschereignisse achten oder auf Änderungen jeglicher Art an einem Pfad warten. Cloud-Funktionen unterstützen diese Ereignishandler für die Echtzeitdatenbank:

Geben Sie die Instanz und den Pfad an

Um zu steuern, wann und wo Ihre Funktion ausgelöst werden soll, rufen Sie ref(path) auf, um einen Pfad anzugeben, und geben Sie optional eine Echtzeitdatenbankinstanz mit instance('INSTANCE_NAME') . Wenn Sie keine Instanz angeben, wird die Funktion auf der Standardinstanz der Echtzeitdatenbank für das Firebase-Projekt bereitgestellt. Beispiel:

  • Standardinstanz der Echtzeitdatenbank: functions.database.ref('/foo/bar')
  • Instanz mit dem Namen "my-app-db-2": functions.database.instance('my-app-db-2').ref('/foo/bar')

Diese Methoden weisen Ihre Funktion an, Schreibvorgänge an einem bestimmten Pfad innerhalb der Echtzeitdatenbankinstanz auszuführen. Die Pfadspezifikationen stimmen mit allen Schreibvorgängen überein, die einen Pfad berühren, einschließlich Schreibvorgängen, die irgendwo darunter erfolgen. Wenn Sie den Pfad für Ihre Funktion als /foo/bar festlegen, werden die Ereignisse an beiden folgenden Standorten abgeglichen:

 /foo/bar
 /foo/bar/baz/really/deep/path

In beiden Fällen interpretiert Firebase, dass das Ereignis in /foo/bar auftritt, und die Ereignisdaten enthalten die alten und neuen Daten in /foo/bar . Wenn die Ereignisdaten möglicherweise groß sind, sollten Sie mehrere Funktionen auf tieferen Pfaden anstelle einer einzelnen Funktion in der Nähe des Stammverzeichnisses Ihrer Datenbank verwenden. Fordern Sie für eine optimale Leistung nur Daten auf der tiefstmöglichen Ebene an.

Sie können eine Pfadkomponente als Platzhalter angeben, indem Sie sie mit geschweiften Klammern umgeben. ref('foo/{bar}') entspricht jedem Kind von /foo . Die Werte dieser Platzhalterpfadkomponenten sind im EventContext.params Objekt Ihrer Funktion verfügbar. In diesem Beispiel ist der Wert als event.params.bar verfügbar.

Pfade mit Platzhaltern können mit mehreren Ereignissen aus einem einzigen Schreibvorgang übereinstimmen. Eine Beilage von

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

stimmt zweimal mit dem Pfad "/foo/{bar}" überein: einmal mit "hello": "world" und erneut mit "firebase": "functions" .

Ereignisdaten verarbeiten

Bei der Behandlung eines Echtzeitdatenbankereignisses ist das zurückgegebene Datenobjekt ein DataSnapshot . Bei onWrite oder onUpdate Ereignissen ist der erste Parameter ein Change Objekt, das zwei Snapshots enthält, die den Datenstatus vor und nach dem auslösenden Ereignis darstellen. Bei onCreate und onDelete Ereignissen ist das zurückgegebene Datenobjekt eine Momentaufnahme der erstellten oder gelöschten Daten.

In diesem Beispiel ruft die Funktion den Snapshot für den angegebenen Pfad als snap , konvertiert die Zeichenfolge an dieser Stelle in Großbuchstaben und schreibt diese geänderte Zeichenfolge in die Datenbank:

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return snapshot.ref.parent.child('uppercase').set(uppercase);
    });

Zugriff auf Benutzerauthentifizierungsinformationen

Über EventContext.auth und EventContext.authType können Sie auf die Benutzerinformationen einschließlich der Berechtigungen für den Benutzer zugreifen, der eine Funktion ausgelöst hat. Dies kann nützlich sein, um Sicherheitsregeln durchzusetzen, sodass Ihre Funktion je nach Berechtigungsstufe des Benutzers verschiedene Vorgänge ausführen kann:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.simpleDbFunction = functions.database.ref('/path')
    .onCreate((snap, context) => {
      if (context.authType === 'ADMIN') {
        // do something
      } else if (context.authType === 'USER') {
        console.log(snap.val(), 'written by', context.auth.uid);
      }
    });

Außerdem können Sie Benutzerauthentifizierungsinformationen nutzen, um sich als Benutzer auszugeben und Schreibvorgänge im Namen des Benutzers auszuführen. Stellen Sie sicher, dass Sie die App-Instanz wie unten gezeigt löschen, um Parallelitätsprobleme zu vermeiden:

exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });

Den vorherigen Wert lesen

Das Change Objekt verfügt über eine before Eigenschaft, mit der Sie überprüfen können, was vor dem Ereignis in der Echtzeitdatenbank gespeichert wurde. Die before Eigenschaft gibt einen DataSnapshot bei dem alle Methoden (z. B. val() und exists() ) auf den vorherigen Wert verweisen. Sie können den neuen Wert erneut lesen, indem Sie entweder den ursprünglichen DataSnapshot oder die after Eigenschaft lesen. Diese Eigenschaft bei jeder Change ist ein weiterer DataSnapshot der den Status der Daten nach dem DataSnapshot des Ereignisses darstellt.

Mit der Eigenschaft before kann beispielsweise sichergestellt werden, dass die Funktion beim ersten Erstellen nur Text in Großbuchstaben schreibt:

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite((change, context) => {
      // Only edit data when it is first created.
      if (change.before.exists()) {
        return null;
      }
      // Exit when the data is deleted.
      if (!change.after.exists()) {
        return null;
      }
      // Grab the current value of what was written to the Realtime Database.
      const original = change.after.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return change.after.ref.parent.child('uppercase').set(uppercase);
    });