Sie können Nutzern, die Ihre Erweiterung installieren, die Möglichkeit geben, eigene benutzerdefinierte Logik in die Ausführung Ihrer Erweiterung einzufügen. Dazu gibt es zwei Möglichkeiten:
Eventarc-Ereignisse: Wenn Sie Nutzern die Möglichkeit geben möchten, asynchron auf Ereignisse zu reagieren, können Sie Ereignisse in Eventarc veröffentlichen. Nutzer können Event-Handler-Funktionen bereitstellen, die beispielsweise Benachrichtigungen senden, nachdem lang andauernde Aufgaben abgeschlossen sind. Sie können auch eigene Nachbearbeitungsfunktionen definieren.
Synchrone Hooks: Wenn Sie Nutzern die Möglichkeit geben möchten, Ihrer Erweiterung blockierende Logik hinzuzufügen, können Sie synchrone Hooks an vordefinierten Stellen im Betrieb der Erweiterung hinzufügen. An diesen Stellen führen Sie eine vom Nutzer bereitgestellte Funktion aus und fahren erst fort, wenn sie abgeschlossen ist. Aufgaben zur Vorverarbeitung fallen häufig in diese Kategorie.
Eine Erweiterung kann eine oder beide Methoden verwenden.
Eventarc-Ereignisse
So veröffentlichen Sie Ereignisse aus einer Erweiterung:
Deklarieren Sie die Ereignistypen, die Sie veröffentlichen möchten, in der Datei
extension.yaml:events: - type: publisher-id.extension-name.version.event-name description: event-description - type: publisher-id.extension-name.version.another-event-name description: another-event-descriptionDie Kennung
typebesteht aus mehreren durch Punkte getrennten Feldern. Die Felder für die Publisher-ID, den Erweiterungsnamen und den Ereignisnamen sind erforderlich. Das Feld „Version“ wird empfohlen. Wählen Sie für jeden Ereignistyp, den Sie veröffentlichen, einen eindeutigen und beschreibenden Ereignisnamen aus.Die Erweiterung
storage-resize-imagesdeklariert beispielsweise einen einzelnen Ereignistyp:events: - type: firebase.extensions.storage-resize-images.v1.complete description: | Occurs when image resizing completes. The event will contain further details about specific formats and sizes.Nutzer können bei der Installation der Erweiterung auswählen, welche Ereignisse sie abonnieren möchten.
Importieren Sie in Ihren Erweiterungsfunktionen die Eventarc API aus dem Admin SDK und initialisieren Sie einen Ereigniskanal mit den Installationseinstellungen des Nutzers. Diese Einstellungen werden über die folgenden Umgebungsvariablen verfügbar gemacht:
EVENTARC_CHANNEL: der vollständig qualifizierte Name des Eventarc-Kanals, in dem der Nutzer Ereignisse veröffentlichen möchte.EXT_SELECTED_EVENTS: eine durch Kommas getrennte Liste der Ereignistypen, die der Nutzer veröffentlichen möchte. Wenn Sie einen Kanal mit diesem Wert initialisieren, filtert das Admin SDK automatisch Ereignisse heraus, die der Nutzer nicht ausgewählt hat.EVENTARC_CLOUD_EVENT_SOURCE: die Quell-ID des Cloud-Ereignisses. Das Admin SDK übergibt diesen Wert automatisch im Feldsourceder veröffentlichten Ereignisse. In der Regel müssen Sie diese Variable nicht explizit verwenden.
Wenn Ereignisse bei der Installation nicht aktiviert wurden, sind diese Variablen nicht definiert. Sie können diese Tatsache nutzen, um einen Ereigniskanal nur zu initialisieren, wenn Ereignisse aktiviert sind:
import * as admin from "firebase-admin"; import {getEventarc} from 'firebase-admin/eventarc'; admin.initializeApp(); // Set eventChannel to a newly-initialized channel, or `undefined` if events // aren't enabled. const eventChannel = process.env.EVENTARC_CHANNEL && getEventarc().channel(process.env.EVENTARC_CHANNEL, { allowedEventTypes: process.env.EXT_SELECTED_EVENTS, });Veröffentlichen Sie Ereignisse an den Stellen in Ihrer Erweiterung, die Sie Nutzern zur Verfügung stellen möchten. Beispiel:
// If events are enabled, publish a `complete` event to the configured // channel. eventChannel && eventChannel.publish({ type: 'firebase.extensions.storage-resize-images.v1.complete', subject: filename, // the name of the original file data: { // ... } });Dokumentieren Sie die Ereignisse, die Sie veröffentlichen, entweder in der Datei PREINSTALL oder POSTINSTALL.
Dokumentieren Sie für jedes Ereignis Folgendes:
- Verwendungszweck
- Die Stelle in der Logik Ihrer Erweiterung, an der sie ausgeführt wird
- Die Ausgabedaten, die sie enthält
- Die Bedingungen für die Ausführung
Warnen Sie Nutzer außerdem davor, in ihren Event-Handlern Aktionen auszuführen, die dieselbe Erweiterung auslösen könnten, was zu einer Endlosschleife führen würde.
Wenn Sie Ereignisse aus einer Erweiterung veröffentlichen, können Nutzer Event-Handler bereitstellen, um mit benutzerdefinierter Logik zu reagieren.
Im folgenden Beispiel wird das Originalbild gelöscht, nachdem seine Größe geändert wurde. Beachten Sie, dass in diesem Beispiel-Handler die Eigenschaft subject des Ereignisses verwendet wird, die in diesem Fall der ursprüngliche Dateiname des Bildes ist.
exports.onimageresized = onCustomEventPublished(
"firebase.extensions.storage-resize-images.v1.complete",
(event) => {
logger.info("Received image resize completed event", event);
// For example, delete the original.
return admin.storage()
.bucket("my-project.firebasestorage.app")
.file(event.subject)
.delete();
});
Weitere Informationen finden Sie unter Benutzerdefinierte Ereignistrigger für weitere Informationen.
Beispiel
Die offizielle Resize Images extension bietet einen asynchronen Hook, indem sie nach dem Ändern der Größe eines Bildes in Eventarc veröffentlicht.
Synchrone Hooks
Wenn Sie Nutzern einen Hook zur Verfügung stellen möchten, der erfolgreich abgeschlossen werden muss, damit eine Ihrer Erweiterungsfunktionen ausgeführt werden kann, verwenden Sie synchrone Hooks.
Ein synchroner Hook ruft eine vom Nutzer definierte HTTPS-aufrufbare Cloud Funktion auf und wartet auf den Abschluss (möglicherweise mit einem Rückgabewert), bevor er fortfährt. Ein Fehler in der vom Nutzer bereitgestellten Funktion führt zu einem Fehler in der Erweiterungsfunktion.
So stellen Sie einen synchronen Hook zur Verfügung:
Fügen Sie Ihrer Erweiterung einen Parameter hinzu, mit dem Nutzer die Erweiterung mit der URL zu ihrer benutzerdefinierten Cloud-Funktion konfigurieren können. Beispiel:
- param: PREPROCESSING_FUNCTION label: Pre-processing function URL description: > An HTTPS callable function that will be called to transform the input data before it is processed by this function. type: string example: https://us-west1-my-project-id.cloudfunctions.net/preprocessData required: falseRufen Sie die Funktion an der Stelle in Ihrer Erweiterung auf, an der Sie den Hook zur Verfügung stellen möchten, über die URL auf. Beispiel:
const functions = require('firebase-functions/v1'); const fetch = require('node-fetch'); const preprocessFunctionURL = process.env.PREPROCESSING_FUNCTION; exports.yourFunctionName = functions.firestore.document("collection/{doc_id}") .onWrite((change, context) => { // PREPROCESSING_FUNCTION hook begins here. // If a preprocessing function is defined, call it before continuing. if (preprocessFunctionURL) { try { await fetch(preprocessFunctionURL); // Could also be a POST request if you want to send data. } catch (e) { // Preprocessing failure causes the function to fail. functions.logger.error("Preprocessor error:", e); return; } } // End of PREPROCESSING_FUNCTION hook. // Main function logic follows. // ... });Dokumentieren Sie alle Hooks, die Sie zur Verfügung stellen, entweder in der Datei PREINSTALL oder POSTINSTALL.
Dokumentieren Sie für jeden Hook Folgendes:
- Verwendungszweck
- Die Stelle in der Logik Ihrer Erweiterung, an der sie ausgeführt wird
- Die erwarteten Ein- und Ausgaben
- Die Bedingungen (oder Optionen) für die Ausführung
Warnen Sie Nutzer außerdem davor, in der Hook-Funktion Aktionen auszuführen, die dieselbe Erweiterung auslösen könnten, was zu einer Endlosschleife führen würde.
Beispiel
Die Erweiterung „Algolia Search“ bietet einen synchronen Hook, um vor dem Schreiben in Algolia eine vom Nutzer bereitgestellte Transformationsfunktion aufzurufen.