Możesz umożliwić użytkownikom instalującym Twoje rozszerzenie wstawianie własnej logiki niestandardowej do jego wykonania. Możesz to zrobić na 2 sposoby:
Zdarzenia Eventarc: aby umożliwić użytkownikom asynchroniczne reagowanie na zdarzenia, możesz publikować je w Eventarc. Użytkownicy mogą wdrażać funkcje obsługi zdarzeń, które np. wysyłają powiadomienia po zakończeniu długotrwałych zadań, lub definiować własne funkcje przetwarzania końcowego.
Synchroniczne punkty zaczepienia: aby umożliwić użytkownikom dodawanie logiki blokującej do rozszerzenia, możesz dodać synchroniczne punkty zaczepienia w predefiniowanych miejscach działania rozszerzenia. W tych miejscach uruchamiasz funkcję dostarczoną przez użytkownika i kontynuujesz działanie dopiero po jej zakończeniu. Zadania przetwarzania wstępnego często należą do tej kategorii.
Rozszerzenie może korzystać z jednej lub obu tych metod.
Zdarzenia Eventarc
Aby publikować zdarzenia z rozszerzenia:
Zadeklaruj typy zdarzeń, które będziesz publikować, w pliku
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-descriptionIdentyfikator
typeskłada się z kilku pól rozdzielonych kropkami. Pola identyfikatora wydawcy, nazwy rozszerzenia i nazwy zdarzenia są wymagane. Pole wersji jest zalecane. Wybierz unikalną i opisową nazwę zdarzenia dla każdego publikowanego typu zdarzenia.Na przykład rozszerzenie
storage-resize-imagesdeklaruje jeden typ zdarzenia: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.Podczas instalowania rozszerzenia użytkownicy będą mogli wybrać, które zdarzenia chcą subskrybować.
W funkcjach rozszerzenia zaimportuj interfejs Eventarc API z pakietu Admin SDK i zainicjuj kanał zdarzeń za pomocą ustawień instalacji użytkownika. Te ustawienia są udostępniane za pomocą tych zmiennych środowiskowych:
EVENTARC_CHANNEL: pełna nazwa kanału Eventarc, w którym użytkownik wybrał publikowanie zdarzeń.EXT_SELECTED_EVENTS: rozdzielona przecinkami lista typów zdarzeń, które użytkownik wybrał do publikowania. Gdy zainicjujesz kanał z tą wartością, pakiet Admin SDK automatycznie odfiltruje zdarzenia, których użytkownik nie wybrał.EVENTARC_CLOUD_EVENT_SOURCE: identyfikator źródła Cloud Event. Pakiet Admin SDK automatycznie przekazuje tę wartość w polusourceopublikowanych zdarzeń. Zazwyczaj nie musisz jawnie używać tej zmiennej.
Jeśli zdarzenia nie zostały włączone podczas instalacji, te zmienne będą niezdefiniowane. Możesz użyć tej informacji, aby zainicjować kanał zdarzeń tylko wtedy, gdy zdarzenia są włączone:
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, });Publikuj zdarzenia w kanale w miejscach rozszerzenia, które chcesz udostępnić użytkownikom. Przykład:
// 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: { // ... } });Opisz publikowane zdarzenia w pliku PREINSTALL lub POSTINSTALL.
W przypadku każdego zdarzenia opisz te elementy:
- Zamierzony cel
- Miejsce w logice rozszerzenia, w którym jest uruchamiane
- Dane wyjściowe, które zawiera
- Warunki jego wykonania
Dodatkowo ostrzeż użytkowników, aby nie wykonywali w swoich procedurach obsługi zdarzeń żadnych działań, które mogłyby wywołać to samo rozszerzenie, co spowodowałoby nieskończoną pętlę.
Gdy publikujesz zdarzenia z rozszerzenia, użytkownicy mogą wdrażać procedury obsługi zdarzeń, aby odpowiadać za pomocą logiki niestandardowej.
Na przykład ten przykład usuwa oryginalny obraz po zmianie jego rozmiaru. Pamiętaj, że ta procedura obsługi korzysta z właściwości subject zdarzenia, która w tym przypadku jest oryginalną nazwą pliku obrazu.
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();
});
Więcej informacji znajdziesz w artykule Wyzwalacze zdarzeń niestandardowych.
Przykład
Oficjalne rozszerzenie Resize Images udostępnia asynchroniczny punkt zaczepienia, publikując w Eventarc po zmianie rozmiaru obrazu.
Synchroniczne punkty zaczepienia
Jeśli chcesz udostępnić użytkownikom punkt zaczepienia, który musi zostać pomyślnie zakończony, aby jedna z funkcji rozszerzenia mogła działać, użyj synchronicznych punktów zaczepienia.
Synchroniczny punkt zaczepienia wywołuje zdefiniowaną przez użytkownika funkcję Cloud Functions, którą można wywołać przez HTTPS, i czeka na jej zakończenie (ewentualnie z zwróconą wartością) przed kontynuowaniem. Błąd w funkcji dostarczonej przez użytkownika powoduje błąd w funkcji rozszerzenia.
Aby udostępnić synchroniczny punkt zaczepienia:
Dodaj do rozszerzenia parametr, który umożliwi użytkownikom skonfigurowanie rozszerzenia za pomocą adresu URL niestandardowej funkcji Cloud Functions. Przykład:
- 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: falseW miejscu rozszerzenia, w którym chcesz udostępnić punkt zaczepienia, wywołaj funkcję za pomocą jej adresu URL. Przykład:
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. // ... });Opisz wszystkie udostępniane punkty zaczepienia w pliku PREINSTALL lub POSTINSTALL.
W przypadku każdego punktu zaczepienia opisz te elementy:
- Zamierzony cel
- Miejsce w logice rozszerzenia, w którym jest uruchamiany
- Oczekiwane dane wejściowe i wyjściowe
- Warunki (lub opcje) jego wykonania
Dodatkowo ostrzeż użytkowników, aby nie wykonywali w funkcji punktu zaczepienia żadnych działań, które mogłyby wywołać to samo rozszerzenie, co spowodowałoby nieskończoną pętlę.
Przykład
Rozszerzenie Algolia Search udostępnia synchroniczny punkt zaczepienia, który umożliwia wywołanie dostarczonej przez użytkownika funkcji transformacji przed zapisaniem w Algolii.