Możesz umożliwić użytkownikom, którzy zainstalują Twoje rozszerzenie, wstawianie własnej logiki niestandardowej podczas jego działania. 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 ukończeniu długotrwałych zadań, lub definiować własne funkcje końcowe.
Synchroniczne hooki: aby umożliwić użytkownikom dodanie logiki blokującej do rozszerzenia, możesz dodać synchroniczne punkty zaczepienia w zdefiniowanych wstępnie punktach działania rozszerzenia. W tych miejscach uruchamiasz funkcję dostawcy danych użytkownika i kontynuujesz dopiero po jej zakończeniu. Do tej kategorii często zaliczają się zadania wstępnego przetwarzania.
Rozszerzenie może używać jednej lub obu tych metod.
Zdarzenia Eventarc
Aby opublikować zdarzenia z rozszerzenia:
Zadeklaruj typy zdarzeń, które chcesz 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-description
Identyfikator
type
składa się z kilku pól rozdzielanych kropkami. Pola identyfikator wydawcy, nazwa rozszerzenia i nazwa zdarzenia są wymagane. Pole wersji jest zalecane. Każdemu rodzajowi zdarzenia, które publikujesz, wybierz unikalną i opisową nazwę.Na przykład rozszerzenie
storage-resize-images
deklaruje 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.
Po zainstalowaniu rozszerzenia użytkownicy będą mogli wybrać, na które wydarzenia chcą się zapisać.
W funkcjach rozszerzenia zaimportuj interfejs Eventarc API z Admin SDKi inicjuj kanał zdarzeń, używając ustawień instalacji użytkownika. Te ustawienia są dostępne za pomocą tych zmiennych środowiskowych:
EVENTARC_CHANNEL
: w pełni kwalifikowana nazwa kanału Eventarc, w którym użytkownik wybrał publikowanie zdarzeń.EXT_SELECTED_EVENTS
: lista oddzielonych przecinkami typów wydarzeń, które użytkownik chce opublikować. Gdy zainicjujesz kanał przy użyciu tej wartości, pakiet Admin SDK automatycznie odfiltruje zdarzenia, które nie zostały wybrane przez użytkownika.EVENTARC_CLOUD_EVENT_SOURCE
: identyfikator źródła zdarzenia Cloud. Pakiet Admin SDK automatycznie przekazuje tę wartość w polusource
opublikowanych zdarzeń. Zwykle nie trzeba jawnie używać tej zmiennej.
Jeśli zdarzenia nie były włączone podczas instalacji, zmienne te pozostaną niezdefiniowane. Możesz użyć tego faktu, 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 na kanale zdarzenia 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: { // ... } });
Udokumentuj publikowane zdarzenia w pliku PREINSTALL lub POSTINSTALL.
W przypadku każdego wydarzenia udokumentuj te informacje:
- Przeznaczenie
- Punkt w logice rozszerzenia, w którym jest ono wykonywane
- zawarte w nim dane wyjściowe,
- warunki jego wykonania;
Dodatkowo ostrzegaj użytkowników, aby nie wykonywali w ich modułach obsługi zdarzeń żadnych działań, które mogą aktywować to samo rozszerzenie i stworzyć pętlę nieskończoną.
Gdy opublikujesz zdarzenia z poziomu rozszerzenia, użytkownicy będą mogli stosować ich obsługi, aby reagować na nie za pomocą logiki niestandardowej.
W przykładzie poniżej widać usunięcie oryginalnego obrazu po zmianie jego rozmiaru. Zwróć uwagę, że w tym przykładowym module obsługi używana jest właściwość subject
zdarzenia – w tym przypadku jest to pierwotna nazwa 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.appspot.com")
.file(event.subject)
.delete();
});
Więcej informacji znajdziesz w sekcji Wyzwalacze zdarzeń niestandardowych.
Przykład
Oficjalne rozszerzenie do zmiany rozmiaru obrazu zapewnia asynchroniczny element wywoławczy, który publikuje w Eventarc po zmianie rozmiaru obrazu.
Elementy synchroniczne
Jeśli chcesz udostępnić użytkownikom element wywołania, który musi zostać wykonany prawidłowo, aby jedna z funkcji rozszerzenia mogła działać, użyj elementów wywołania synchronicznego.
Synchroniczny punkt zaczepienia wywołuje zdefiniowaną przez użytkownika funkcję wywoływania przez HTTPS w Cloud Functions i oczekuje na zakończenie (prawdopodobnie z zwróconą wartością), zanim przejdziesz dalej. Błąd w funkcji podanej przez użytkownika powoduje błąd w funkcji rozszerzenia.
Aby ujawnić element synchroniczny:
Dodaj do rozszerzenia parametr, który pozwoli użytkownikom skonfigurować rozszerzenie za pomocą adresu URL niestandardowej funkcji w Cloud. 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: false
W miejscu w rozszerzeniu, w którym chcesz ujawnić element wywołania, 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. // ... });
Zapisz wszystkie dostępne punkty wywołania w pliku PREINSTALL lub POSTINSTALL.
W przypadku każdego elementu zaczepu opisz te informacje:
- Zamierzone zastosowanie
- Punkt w logice rozszerzenia, w którym jest ono wykonywane
- oczekiwane dane wejściowe i wyjściowe;
- warunki (lub opcje) wykonania kodu;
Dodatkowo ostrzegaj użytkowników, aby nie wykonywali żadnych działań w funkcji hook, które mogłyby wywołać to samo rozszerzenie, powodując nieskończoną pętlę.
Przykład
Rozszerzenie Algolia Search zapewnia synchroniczny element wywoływania funkcji przekształcenia dostarczonej przez użytkownika przed zapisaniem danych w Algolii.