Mit Cloud Functions können Sie Ereignisse in der Firebase Realtime Database verarbeiten, ohne den Clientcode aktualisieren zu müssen.
Mit Cloud Functions können Sie Realtime Database-Vorgänge mit vollem Verwaltungsaufwand ausführen
Berechtigungen und stellt sicher, dass jede Änderung an Realtime Database verarbeitet wird.
individuell anpassen. Sie können Firebase Realtime Database Änderungen vornehmen über das
DataSnapshot
oder über das Admin SDK.
In einem typischen Lebenszyklus führt eine Firebase Realtime Database-Funktion so vor:
- Sie wartet auf Änderungen an einem bestimmten Realtime Database-Speicherort.
- Sie wird ausgelöst, wenn ein Ereignis eintritt, und führt dessen Aufgaben aus (siehe Was kann ich mit Cloud Functions tun? finden Sie Beispiele für Anwendungsfälle).
- Sie empfängt ein Datenobjekt, das einen Snapshot der gespeicherten Daten enthält im angegebenen Dokument.
Realtime Database-Funktion auslösen
Mit functions.database
können Sie neue Funktionen für Realtime Database-Ereignisse erstellen. Bis
steuern, wann die Funktion ausgelöst wird, geben Sie einen der Event-Handler an und
Geben Sie den Pfad Realtime Database an, unter dem auf Ereignisse überwacht wird.
Event-Handler festlegen
Mit Funktionen können Sie Realtime Database-Ereignisse mit zwei Spezifitätsgraden verarbeiten: speziell für Erstellung, Aktualisierung, oder Lösch-Ereignissen oder Sie können auf jede beliebige Änderung eines Pfads warten. Cloud Functions unterstützt die folgenden Ereignishandler für Realtime Database:
onWrite()
: wird ausgelöst, wenn Daten in Realtime Database erstellt, aktualisiert oder gelöscht werden.onCreate()
, was ausgelöst wird, wenn in Realtime Database neue Daten erstellt werdenonUpdate()
, der ausgelöst wird, wenn Daten in Realtime Database aktualisiert werden.onDelete()
, was ausgelöst wird, wenn Daten aus Realtime Database gelöscht werden .
Instanz und Pfad angeben
Wenn Sie festlegen möchten, wann und wo Ihre Funktion ausgelöst werden soll, rufen Sie ref(path)
auf, um einen Pfad anzugeben, und optional eine Realtime Database-Instanz mit instance('INSTANCE_NAME')
. Wenn Sie keine Instanz angeben, wird die Funktion in der Standard-Realtime Database-Instanz für das Firebase-Projekt bereitgestellt. Beispiel:
- Standard-Realtime Database-Instanz:
functions.database.ref('/foo/bar')
- Instanz mit dem Namen „my-app-db-2“:
functions.database.instance('my-app-db-2').ref('/foo/bar')
Mit diesen Methoden wird Ihre Funktion angewiesen, Schreibvorgänge an einem bestimmten Pfad innerhalb der Realtime Database-Instanz zu verarbeiten. Die Pfadspezifikationen gleichen alle Schreibvorgänge ab, die einen Pfad tangieren, einschließlich Schreibvorgängen, die an einem beliebigen untergeordneten Punkt auftreten. Wenn Sie als Pfad für Ihre Funktion /foo/bar
festlegen, werden die Ereignisse an diesen beiden Speicherorten abgeglichen:
/foo/bar
/foo/bar/baz/really/deep/path
In beiden Fällen geht Firebase davon aus, dass das Ereignis unter /foo/bar
auftritt,
und die Ereignisdaten enthalten
die alten und neuen Daten unter /foo/bar
. Bei großen Ereignisdaten
Verwenden Sie mehrere Funktionen für tiefere Pfade anstelle eines einzelnen
in der Nähe des Stammverzeichnisses
Ihrer Datenbank. Für optimale Leistung sollten Sie Daten nur auf der untersten Ebene anfordern.
Sie können eine Pfadkomponente als Platzhalter angeben, indem Sie sie in geschweifte Klammern setzen
Klammern; ref('foo/{bar}')
stimmt mit jedem untergeordneten Element von /foo
überein. Die Werte dieser Platzhalterpfadkomponenten sind innerhalb des EventContext.params
-Objekts Ihrer Funktion verfügbar. In diesem Beispiel ist der Wert als
context.params.bar
Pfade mit Platzhaltern können mit mehreren Ereignissen aus einem einzigen Schreibvorgang übereinstimmen. Eine Einfügung von
{
"foo": {
"hello": "world",
"firebase": "functions"
}
}
ergibt zwei Übereinstimmungen mit dem Pfad "/foo/{bar}"
: einmal "hello": "world"
und einmal "firebase": "functions"
.
Ereignisdaten verarbeiten
Bei der Verarbeitung eines Realtime Database-Ereignisses wird ein DataSnapshot
-Datenobjekt zurückgegeben.
Für onWrite
- oder onUpdate
-Ereignisse:
Der erste Parameter ist ein Change
-Objekt, das zwei Snapshots enthält.
die den Datenzustand vor
und nach dem auslösenden Ereignis. Bei onCreate
- und onDelete
-Ereignissen ist das zurückgegebene Datenobjekt ein Snapshot der erstellten oder gelöschten Daten.
In diesem Beispiel ruft die Funktion den Snapshot für den angegebenen Pfad ab, wandelt den String an dieser Stelle in Großbuchstaben um und schreibt den geänderten String 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(); functions.logger.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); });
Auf Informationen zur Nutzerauthentifizierung zugreifen
Über EventContext.auth
und EventContext.authType
können Sie auf die Nutzerinformationen, einschließlich Berechtigungen, des Nutzers zugreifen, der eine Funktion ausgelöst hat. Das kann hilfreich sein, um Sicherheitsregeln durchzusetzen und Ihrer Funktion je nach Berechtigungsstufe des Nutzers unterschiedliche Vorgänge ausführen zu lassen:
const functions = require('firebase-functions/v1');
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);
}
});
Sie können sich auch mithilfe von Informationen zur Nutzerauthentifizierung ein Nutzer und Schreibvorgänge im Namen des Nutzers ausführen. Vergessen Sie nicht, die App-Instanz wie unten gezeigt, um Gleichzeitigkeitsprobleme 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));
});
});
Vorherigen Wert lesen
Das Change
-Objekt hat einen
before
können Sie überprüfen, was Realtime Database vor der
. Das Attribut before
gibt einen DataSnapshot
-Wert zurück, bei dem alle
(z. B.
val()
und
exists()
)
auf den vorherigen Wert. Sie können den neuen Wert entweder mit
Original-DataSnapshot
oder Lesen der
after
Property. Diese Property bei einer Change
ist eine weitere DataSnapshot
, die den Status der Daten nach dem Ereignis darstellt.
Beispielsweise kann das Attribut before
verwendet werden, um dafür zu sorgen, dass die Funktion nur
Text bei seiner Erstellung in Großbuchstaben:
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);
});