Ihre Erweiterung kann Cloud Tasks Funktionen enthalten, die ausgelöst werden, wenn eine Erweiterungsinstanz eines der folgenden Lebenszyklusereignisse durchläuft:
- Eine Instanz der Erweiterung wird installiert
- Eine Instanz der Erweiterung wird auf eine neue Version aktualisiert
- Die Konfiguration einer Erweiterungsinstanz wird geändert
Einer der wichtigsten Anwendungsfälle für diese Funktion ist das nachträgliche Ausfüllen von Daten. Angenommen, Sie entwickeln eine Erweiterung, die Miniaturansichten
von Bildern generiert, die in einen Cloud Storage Bucket hochgeladen wurden. Die Hauptarbeit Ihrer Erweiterung
würde in einer Funktion ausgeführt, die durch das onFinalize Cloud Storage Ereignis ausgelöst wird.
Es würden jedoch nur Bilder verarbeitet, die nach der Installation der Erweiterung hochgeladen wurden. Wenn Sie in Ihre Erweiterung eine Funktion einfügen, die durch das
onInstall Lifecycle-Event ausgelöst wird, können Sie auch Miniaturansichten von
vorhandenen Bildern generieren, wenn die Erweiterung installiert wird.
Weitere Anwendungsfälle für Lifecycle-Event-Trigger:
- Automatisieren der Einrichtung nach der Installation (Erstellen von Datenbankeinträgen, Indexierung usw.)
- Wenn Sie abwärtsinkompatible Änderungen veröffentlichen müssen, werden Daten bei der Aktualisierung automatisch migriert
Kurz laufende Lifecycle-Event-Handler
Wenn Ihre Aufgabe vollständig innerhalb der
maximalen Cloud Functions Dauer (9
Minuten mit der API der ersten Generation) ausgeführt werden kann, können Sie Ihren Lifecycle-Event-Handler als einzelne Funktion schreiben, die durch das Aufgabenwarteschlangen-onDispatch Ereignis 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 Datei extension.yaml Ihrer Erweiterung die folgenden Schritte aus:
Registrieren Sie Ihre Funktion als Erweiterungsressource mit dem Attribut
taskQueueTrigger. Wenn SietaskQueueTriggerauf die leere Map ({}) setzen, stellt Ihre Erweiterung eine Cloud Tasks Warteschlange mit den Standard einstellungen bereit. 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 extensionSie können Funktionen für alle folgenden Ereignisse registrieren:
onInstall,onUpdateundonConfigure. Alle diese Ereignisse sind optional.Empfohlen: Wenn die Verarbeitungsaufgabe nicht erforderlich ist, damit Ihre Erweiterung funktioniert, fügen Sie einen vom Nutzer konfigurierten Parameter hinzu, mit dem Nutzer auswählen können, ob sie sie 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: falseWenn der Parameter in Ihrer Funktion auf
falsegesetzt ist, beenden Sie die Funktion vorzeitig: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 laufende Aufgaben ausführen
Wenn Ihre Aufgabe nicht innerhalb der maximalen Cloud Functions Dauer abgeschlossen werden kann,
teilen Sie die Aufgabe 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 ausfüllen. Sie können die Dokumentsammlung mit Abfragecursorn in Blöcke aufteilen. Nach der Verarbeitung eines Blocks erhöhen Sie den Start-Offset und stellen einen weiteren Funktionsaufruf in die Warteschlange, 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 wie im
vorherigen Abschnitt beschrieben zu extension.yaml hinzu.
Status melden
Wenn alle Ihre Verarbeitungsfunktionen abgeschlossen sind, entweder erfolgreich oder mit einem Fehler, melden Sie den Status der Aufgabe mit den Erweiterungslaufzeitmethoden des Admin SDK. Nutzer können diesen Status auf der Detailseite der Erweiterung in der Firebase Console sehen.
Erfolgreicher Abschluss und nicht schwerwiegende Fehler
Verwenden Sie die Erweiterungslaufzeitmethode setProcessingState() des Admin SDK, um einen erfolgreichen Abschluss und nicht schwerwiegende Fehler zu melden (Fehler, die die Erweiterung nicht in einen nicht funktionsfähigen Zustand versetzen):
import { getExtensions } from "firebase-admin/extensions";
// ...
getExtensions().runtime().setProcessingState(processingState, message);
Sie können die folgenden Status festlegen:
| Status vom Typ „Nicht schwerwiegend“ | |
|---|---|
PROCESSING_COMPLETE |
Verwenden Sie diese Option, um einen erfolgreichen Abschluss der Aufgabe zu melden. Beispiel: getExtensions().runtime().setProcessingState( "PROCESSING_COMPLETE", `Backfill complete. Successfully processed ${numSuccess} documents.` ); |
PROCESSING_WARNING |
Verwenden Sie diese Option, 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 |
Verwenden Sie diese Option, 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}.` ); Verwenden Sie |
NONE |
Verwenden Sie diese Option, um den Status der Aufgabe zu löschen. Optional können Sie damit die Statusmeldung aus der Console löschen (z. B. nachdem seit dem Festlegen von getExtensions().runtime().setProcessingState("NONE"); |
Schwerwiegende Fehler
Wenn ein Fehler auftritt, der verhindert, dass die Erweiterung funktioniert, 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 das Attribut taskQueueTrigger auf {} setzen, stellt Ihre Erweiterung beim Installieren einer Erweiterungsinstanz eine Cloud Tasks-Warteschlange mit den Standardeinstellungen bereit. Alternativ können Sie die Grenzwerte für die Nebenläufigkeit 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.
Geben Sie keine Parameter für die Aufgabenwarteschlange an, indem Sie sie an taskQueue() übergeben.
Diese Einstellungen werden zugunsten der Konfiguration in extension.yaml und der Standardkonfiguration 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 storage-resize-images,
firestore-bigquery-export,
und firestore-translate-text
Erweiterungen verwenden alle Lifecycle-Event-Handler, um Daten nachträglich auszufüllen.