Sie können Nutzern, die Ihre Erweiterung installieren, die Möglichkeit geben, ihre eigene benutzerdefinierte Logik in die Ausführung Ihrer Erweiterung einzufügen. Dazu gibt es zwei Möglichkeiten:
Eventarc-Ereignisse: Sie können in Eventarc veröffentlichen, damit Nutzer asynchron auf Ereignisse reagieren können. Nutzer können Ereignis-Handler-Funktionen bereitstellen, die beispielsweise Benachrichtigungen senden, nachdem lang laufende Aufgaben abgeschlossen sind, oder eigene Funktionen zur Nachbearbeitung definieren.
Synchrone Hooks: Damit Nutzer Ihrer Erweiterung eine Blockierungslogik hinzufügen können, können Sie an vordefinierten Stellen in der Funktion der Erweiterung synchrone Hooks hinzufügen. An diesen Stellen führen Sie eine Nutzeranbieterfunktion aus und fahren erst fort, wenn sie abgeschlossen ist. Aufgaben der Vorverarbeitung fallen oft in diese Kategorie.
Für eine Erweiterung kann entweder eine oder beide Methoden verwendet werden.
Eventarc-Ereignisse
So veröffentlichen Sie Ereignisse aus einer Erweiterung:
Deklarieren Sie die Ereignistypen, die Sie in der
extension.yaml
-Datei veröffentlichen möchten:events: - type: publisher-id.extension-name.version.event-name description: event-description - type: publisher-id.extension-name.version.another-event-name description: another-event-description
Die
type
-Kennung besteht aus mehreren durch Punkte getrennten Feldern. Die Felder Publisher-ID, Erweiterungsname und Ereignisname sind erforderlich. Das Versionsfeld wird empfohlen. Wählen Sie für jeden von Ihnen veröffentlichten Ereignistyp einen eindeutigen und beschreibenden Ereignisnamen aus.Die Erweiterung
storage-resize-images
deklariert 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 beim Installieren der Erweiterung auswählen, welche Ereignisse sie abonnieren möchten.
Importieren Sie in Ihren Erweiterungsfunktionen die Eventarc API aus der Admin SDK und initialisieren Sie einen Ereigniskanal mit den Installationseinstellungen des Nutzers. Diese Einstellungen werden über die folgenden Umgebungsvariablen freigegeben:
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 Channel mit diesem Wert initialisieren, werden vom Admin SDK automatisch Ereignisse herausgefiltert, die der Nutzer nicht ausgewählt hat.EVENTARC_CLOUD_EVENT_SOURCE
: die Cloud-Ereignis-Quell-ID. Der Wert wird vom Admin SDK automatisch im Feldsource
veröffentlichter Ereignisse übergeben. Sie müssen diese Variable in der Regel nicht explizit verwenden.
Wenn Ereignisse bei der Installation nicht aktiviert wurden, sind diese Variablen nicht definiert. Sie können einen Ereigniskanal nur dann 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, an denen sie Nutzern angezeigt werden sollen. 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 von Ihnen veröffentlichten Ereignisse entweder in der Datei PREINSTALL oder POSTINSTALL.
Dokumentieren Sie für jedes Ereignis Folgendes:
- Verwendungszweck
- Der Punkt in der Logik Ihrer Erweiterung, an dem sie ausgeführt wird
- Die enthaltenen Ausgabedaten
- Die Bedingungen für die Ausführung
Außerdem sollten Nutzer in ihren Ereignishandlern keine Aktionen ausführen, die dieselbe Erweiterung auslösen könnten, was zu einer unendlichen Schleife 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 beispielsweise gelöscht, nachdem es neu skaliert wurde. In diesem Beispiel-Handler wird die Eigenschaft subject
des Ereignisses verwendet, in diesem Fall der ursprüngliche Dateiname des Bilds.
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.appspot.com")
.file(event.subject)
.delete();
});
Weitere Informationen finden Sie unter Benutzerdefinierte Ereignistrigger.
Beispiel
Die offizielle Erweiterung „Bilder anpassen“ bietet einen asynchronen Hook, indem nach der Größenänderung eines Bildes in Eventarc veröffentlicht wird.
Synchrone Hooks
Wenn Sie Nutzern einen Hook zur Verfügung stellen möchten, der erfolgreich abgeschlossen werden muss, damit eine Ihrer Erweiterungsfunktionen funktioniert, verwenden Sie synchrone Hooks.
Ein synchroner Hook ruft eine benutzerdefinierte HTTPS-aufrufbare Cloud-Funktion auf und wartet auf den Abschluss (ggf. mit einem zurückgegebenen Wert), bevor er fortfährt. Ein Fehler in der vom Nutzer bereitgestellten Funktion führt zu einem Fehler in der Erweiterungsfunktion.
So legen Sie einen synchronen Hook offen:
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: false
Rufen Sie die Funktion an der Stelle in Ihrer Erweiterung auf, an der Sie den Hook freigeben möchten. Verwenden Sie dazu die URL der Funktion. 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 in der Datei PREINSTALL oder POSTINSTALL verfügbar machen.
Dokumentieren Sie für jeden Hook Folgendes:
- Verwendungszweck
- Der Punkt in der Logik Ihrer Erweiterung, an dem sie ausgeführt wird
- Die erwarteten Eingaben und Ausgaben
- Die Bedingungen (oder Optionen) für die Ausführung
Außerdem sollten Sie Nutzer warnen, in der Hook-Funktion keine Aktionen auszuführen, die dieselbe Erweiterung auslösen könnten, was zu einer unendlichen Schleife führen würde.
Beispiel
Die Algolia Search-Erweiterung bietet einen synchronen Hook, mit dem Sie vor dem Schreiben in Algolia eine benutzerdefinierte Transformationsfunktion aufrufen können.