Ihre Erweiterung kann Cloud Tasks-Funktionen enthalten, die ausgelöst werden, wenn eine Erweiterungsinstanz einen der folgenden Lebenszyklusereignisse durchläuft:
- Eine Instanz der Erweiterung ist installiert
- Eine Instanz der Erweiterung wird auf eine neue Version aktualisiert.
- Die Konfiguration einer Erweiterungsinstanz wird geändert
Einer der wichtigsten Anwendungsfälle dieser Funktion ist das Nachladen von Daten. Angenommen, Sie entwickeln eine Erweiterung, die Miniaturansichten von Bildern generiert, die in einen Cloud Storage-Bucket hochgeladen werden. Die Hauptarbeit Ihrer Erweiterung würde in einer Funktion erledigt, die durch das Ereignis onFinalize
Cloud Storage ausgelöst wird.
Es werden jedoch nur Bilder verarbeitet, die nach der Installation der Erweiterung hochgeladen wurden. Wenn Sie in Ihre Erweiterung eine Funktion einfügen, die durch das Lebenszyklusereignis onInstall
ausgelöst wird, können Sie auch Thumbnail-Vorschauen von vorhandenen Bildern generieren, wenn die Erweiterung installiert wird.
Weitere Anwendungsfälle für Lifecycle-Event-Trigger:
- Einrichtung nach der Installation automatisieren (Datenbankeinträge erstellen, indexieren usw.)
- Wenn Sie abwärtsinkompatible Änderungen veröffentlichen müssen, migrieren Sie Daten bei der Aktualisierung automatisch.
Kurz laufende Lebenszyklus-Event-Handler
Wenn Ihr Task vollständig innerhalb der maximalen Cloud Functions-Dauer (9 Minuten bei der API der ersten Generation) ausgeführt werden kann, können Sie den Handler für das Lebenszyklusereignis als einzelne Funktion schreiben, die durch das Ereignis onDispatch
in der Taskwarteschlange ausgelöst wird:
export const myTaskFunction = functions.tasks.taskQueue()
.onDispatch(async () => {
// Complete your lifecycle event handling task.
// ...
// When processing is complete, report status to the user (see below).
});
Führen Sie dann in der extension.yaml
-Datei Ihrer Erweiterung folgende Schritte aus:
Registrieren Sie Ihre Funktion als Erweiterungsressource mit dem Attribut
taskQueueTrigger
. Wenn SietaskQueueTrigger
auf die leere Karte ({}
) festlegen, wird in Ihrer Erweiterung eine Cloud Tasks-Warteschlange mit den Standardeinstellungen bereitgestellt. Sie können diese Einstellungen optional anpassen.resources: - name: myTaskFunction type: firebaseextensions.v1beta.function description: >- Describe the task performed when the function is triggered by a lifecycle event properties: location: ${LOCATION} taskQueueTrigger: {}
Registrieren Sie Ihre Funktion als Handler für ein oder mehrere Lebenszyklusereignisse:
resources: - ... lifecycleEvents: onInstall: function: myTaskFunction processingMessage: Resizing your existing images onUpdate: function: myOtherTaskFunction processingMessage: Setting up your extension onConfigure: function: myOtherTaskFunction processingMessage: Setting up your extension
Sie können Funktionen für die folgenden Ereignisse registrieren:
onInstall
,onUpdate
undonConfigure
. Alle diese Ereignisse sind optional.Empfohlen: Wenn die Verarbeitung nicht erforderlich ist, damit Ihre Erweiterung funktioniert, fügen Sie einen nutzerkonfigurierten Parameter hinzu, mit dem Nutzer auswählen können, ob sie die Verarbeitung aktivieren möchten.
Fügen Sie beispielsweise einen Parameter wie den folgenden hinzu:
params: - param: DO_BACKFILL label: Backfill existing images description: > Should existing, unresized images in the Storage bucket be resized as well? type: select options: - label: Yes value: true - label: No value: false
Wenn der Parameter in Ihrer Funktion auf
false
gesetzt ist, beenden Sie die Funktion frühzeitig:export const myTaskFunction = functions.tasks.taskQueue() .onDispatch(async () => { if (!process.env.DO_BACKFILL) { await runtime.setProcessingState( "PROCESSING_COMPLETE", "Existing images were not resized." ); return; } // Complete your lifecycle event handling task. // ... });
Lang andauernde Aufgaben ausführen
Wenn Ihre Aufgabe nicht innerhalb der maximalen Dauer von Cloud Functions abgeschlossen werden kann, teilen Sie sie in Unteraufgaben auf und führen Sie jede Unteraufgabe nacheinander aus, indem Sie Jobs mit der Methode TaskQueue.enqueue()
des Admin SDK in die Warteschlange stellen.
Angenommen, Sie möchten Cloud Firestore-Daten nachträglich einfügen. Sie können die Dokumentensammlung mit Abfrage-Cursors in Chunks aufteilen. Nach der Verarbeitung eines Chunks müssen Sie den Start-Offset erhöhen und einen weiteren Funktionsaufruf in die Warteschlange stellen, wie unten gezeigt:
import { getFirestore } from "firebase-admin/firestore";
import { getFunctions } from "firebase-admin/functions";
exports.backfilldata = functions.tasks.taskQueue().onDispatch(async (data) => {
// When a lifecycle event triggers this function, it doesn't pass any data,
// so an undefined offset indicates we're on our first invocation and should
// start at offset 0. On subsequent invocations, we'll pass an explicit
// offset.
const offset = data["offset"] ?? 0;
// Get a batch of documents, beginning at the offset.
const snapshot = await getFirestore()
.collection(process.env.COLLECTION_PATH)
.startAt(offset)
.limit(DOCS_PER_BACKFILL)
.get();
// Process each document in the batch.
const processed = await Promise.allSettled(
snapshot.docs.map(async (documentSnapshot) => {
// Perform the processing.
})
);
// If we processed a full batch, there are probably more documents to
// process, so enqueue another invocation of this function, specifying
// the offset to start with.
//
// If we processed less than a full batch, we're done.
if (processed.length == DOCS_PER_BACKFILL) {
const queue = getFunctions().taskQueue(
"backfilldata",
process.env.EXT_INSTANCE_ID
);
await queue.enqueue({
offset: offset + DOCS_PER_BACKFILL,
});
} else {
// Processing is complete. Report status to the user (see below).
}
});
Fügen Sie die Funktion Ihrem extension.yaml
hinzu, wie im vorherigen Abschnitt beschrieben.
Berichtsstatus
Wenn alle Verarbeitungsfunktionen abgeschlossen sind, entweder erfolgreich oder mit einem Fehler, melden Sie den Status des Tasks mit den Methoden der Erweiterungslaufzeit des Admin SDK. Nutzer können diesen Status auf der Seite mit den Erweiterungsdetails in der Firebase-Konsole sehen.
Erfolgreicher Abschluss und nicht schwerwiegende Fehler
Verwenden Sie die Admin SDK-Methode setProcessingState()
, um einen erfolgreichen Abschluss und nicht schwerwiegende Fehler (Fehler, die die Erweiterung nicht in einen nicht funktionsfähigen Zustand versetzen) zu melden:
import { getExtensions } from "firebase-admin/extensions";
// ...
getExtensions().runtime().setProcessingState(processingState, message);
Sie können die folgenden Status festlegen:
Nicht schwerwiegende Zustände | |
---|---|
PROCESSING_COMPLETE |
Wird verwendet, um den erfolgreichen Abschluss einer Aufgabe zu melden. Beispiel: getExtensions().runtime().setProcessingState( "PROCESSING_COMPLETE", `Backfill complete. Successfully processed ${numSuccess} documents.` ); |
PROCESSING_WARNING |
Wird verwendet, um einen Teilerfolg zu melden. Beispiel: getExtensions().runtime().setProcessingState( "PROCESSING_WARNING", `Backfill complete. ${numSuccess} documents processed successfully.` + ` ${numFailed} documents failed to process. ${listOfErrors}.` + ` ${instructionsToFixTheProblem}` ); |
PROCESSING_FAILED |
Wird verwendet, um Fehler zu melden, die verhindern, dass die Aufgabe abgeschlossen wird, die Erweiterung aber nicht unbrauchbar machen. Beispiel: getExtensions().runtime().setProcessingState( "PROCESSING_FAILED", `Backfill failed. ${errorMsg} ${optionalInstructionsToFixTheProblem}.` ); Wenn Sie Fehler melden möchten, die die Erweiterung unbrauchbar machen, rufen Sie |
NONE |
Hiermit wird der Status der Aufgabe gelöscht. Optional können Sie damit die Statusmeldung aus der Konsole entfernen, z. B. nachdem seit dem Festlegen von getExtensions().runtime().setProcessingState("NONE"); |
Schwerwiegende Fehler
Wenn ein Fehler auftritt, der die Funktion der Erweiterung verhindert, z. B. wenn eine erforderliche Einrichtungsaufgabe fehlschlägt, melden Sie den schwerwiegenden Fehler mit setFatalError()
:
import { getExtensions } from "firebase-admin/extensions";
// ...
getExtensions().runtime().setFatalError(`Post-installation setup failed. ${errorMessage}`);
Aufgabenwarteschlange optimieren
Wenn Sie die taskQueueTrigger
-Eigenschaft auf {}
festlegen, wird für Ihre Erweiterung eine Cloud Tasks-Warteschlange mit den Standardeinstellungen bereitgestellt, wenn eine Erweiterungsinstanz installiert wird. Alternativ können Sie die Nebenläufigkeitslimits und das Wiederholungsverhalten der Aufgabenwarteschlange anpassen, indem Sie bestimmte Werte angeben:
resources:
- name: myTaskFunction
type: firebaseextensions.v1beta.function
description: >-
Perform a task when triggered by a lifecycle event
properties:
location: ${LOCATION}
taskQueueTrigger:
rateLimits:
maxConcurrentDispatches: 1000
maxDispatchesPerSecond: 500
retryConfig:
maxAttempts: 100 # Warning: setting this too low can prevent the function from running
minBackoffSeconds: 0.1
maxBackoffSeconds: 3600
maxDoublings: 16
lifecycleEvents:
onInstall:
function: myTaskFunction
processingMessage: Resizing your existing images
onUpdate:
function: myTaskFunction
processingMessage: Setting up your extension
onConfigure:
function: myOtherTaskFunction
processingMessage: Setting up your extension
Weitere Informationen zu diesen Parametern finden Sie in der Google Cloud-Dokumentation unter Cloud Tasks-Warteschlangen konfigurieren.
Versuchen Sie nicht, Parameter für die Aufgabenwarteschlange anzugeben, indem Sie sie an taskQueue()
übergeben.
Diese Einstellungen werden zugunsten der Konfiguration in extension.yaml
und der Standardkonfigurationen ignoriert.
Das funktioniert beispielsweise nicht:
export const myBrokenTaskFunction = functions.tasks
// DON'T DO THIS IN AN EXTENSION! THESE SETTINGS ARE IGNORED.
.taskQueue({
retryConfig: {
maxAttempts: 5,
minBackoffSeconds: 60,
},
rateLimits: {
maxConcurrentDispatches: 1000,
maxDispatchesPerSecond: 10,
},
})
.onDispatch(
// ...
);
Das Attribut taskQueueTrigger
in extension.yaml
ist die einzige Möglichkeit, die Aufgabenwarteschlangen einer Erweiterung zu konfigurieren.
Beispiele
Die offiziellen Erweiterungen storage-resize-images
, firestore-bigquery-export
und firestore-translate-text
verwenden alle Lebenszyklus-Event-Handler, um Daten nachzufüllen.