Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
Puoi fornire agli utenti che installano la tua estensione la possibilità di inserire la propria
logica personalizzata nell'esecuzione dell'estensione. Puoi farlo in due modi:
Eventi Eventarc: per consentire agli utenti di reagire in modo asincrono agli eventi, puoi pubblicare su Eventarc. Gli utenti possono eseguire il deployment di funzioni di gestione degli eventi che, ad esempio, inviano notifiche al termine di attività di lunga durata oppure possono definire le proprie funzioni di post-elaborazione.
Hook sincroni: per consentire agli utenti di aggiungere una logica di blocco all'estensione, puoi aggiungere hook sincroni in punti predefiniti dell'operazione dell'estensione. A questi punti, esegui una funzione di fornitore utente
e procedi solo dopo il completamento. Le attività di pre-elaborazione rientrano spesso in questa categoria.
Un'estensione può utilizzare uno o entrambi i metodi.
Eventi Eventarc
Per pubblicare eventi da un'estensione:
Dichiara i tipi di eventi che pubblicherai nel file extension.yaml:
L'identificatore type è composto da diversi campi delimitati da punti. I campi
ID editore, nome estensione e nome evento sono
obbligatori. Il campo della versione è consigliato. Scegli un nome dell'evento unico e descrittivo
per ogni tipo di evento che pubblichi.
events:-type:firebase.extensions.storage-resize-images.v1.completedescription:|Occurs when image resizing completes. The event will contain furtherdetails about specific formats and sizes.
Gli utenti potranno scegliere a quali eventi iscriversi quando
installano l'estensione.
Nelle funzioni di estensione, importa l'API Eventarc da Admin SDK
e inizializza un canale di eventi utilizzando le impostazioni di installazione dell'utente.
Queste impostazioni vengono esposte utilizzando le seguenti variabili di ambiente:
EVENTARC_CHANNEL: il nome completo del canale Eventarc in cui l'utente ha scelto di pubblicare gli eventi.
EXT_SELECTED_EVENTS: un elenco separato da virgole dei tipi di eventi che l'utente
ha scelto di pubblicare. Quando inizializzi un canale con questo valore, l'SDK Admin filtra automaticamente gli eventi che l'utente non ha selezionato.
EVENTARC_CLOUD_EVENT_SOURCE: l'identificatore dell'origine Cloud Event. L'SDK
Admin trasmette automaticamente questo valore nel campo source degli
eventi pubblicati. In genere non è necessario utilizzare in modo esplicito questa variabile.
Se gli eventi non sono stati attivati durante l'installazione, queste variabili
non saranno definite. Puoi utilizzare questo fatto per inizializzare un canale di eventi solo quando
gli eventi sono abilitati:
import*asadminfrom"firebase-admin";import{getEventarc}from'firebase-admin/eventarc';admin.initializeApp();// Set eventChannel to a newly-initialized channel, or `undefined` if events// aren't enabled.consteventChannel=process.env.EVENTARC_CHANNEL&&
getEventarc().channel(process.env.EVENTARC_CHANNEL,{allowedEventTypes:process.env.EXT_SELECTED_EVENTS,});
Pubblica gli eventi sul canale nei punti dell'estensione che vuoi
mostrare agli utenti. Ad esempio:
// 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 filedata:{// ...}});
Documenta gli eventi che pubblichi nel file PREINSTALL o POSTINSTALL.
Per ogni evento, documenta quanto segue:
Il suo scopo previsto
Il punto della logica dell'estensione in cui viene eseguita
I dati di output che include
Le condizioni per la sua esecuzione
Inoltre, avvisa gli utenti di non eseguire azioni nei gestori di eventi che potrebbero attivare la stessa estensione, causando un loop infinito.
Quando pubblichi eventi da un'estensione, gli utenti possono implementare gestori di eventi
per rispondere con una logica personalizzata.
Ad esempio, il seguente esempio elimina l'immagine originale dopo che è stata
ridimensionata. Tieni presente che questo gestore di esempio utilizza la proprietà subject dell'evento, che in questo caso è il nome file originale dell'immagine.
exports.onimageresized=onCustomEventPublished("firebase.extensions.storage-resize-images.v1.complete",(event)=>{logger.info("Received image resize completed event",event);// For example, delete the original.returnadmin.storage().bucket("my-project.firebasestorage.app").file(event.subject).delete();});
Quando vuoi fornire agli utenti un hook che deve essere completato correttamente
perché una delle tue funzioni di estensione funzioni, utilizza gli hook sincroni.
Un hook sincrono chiama una funzione Cloud richiamabile tramite HTTPS definita dall'utente e attende il completamento (eventualmente con un valore restituito) prima di continuare. Un errore nella funzione fornita dall'utente
comporta un errore nella funzione dell'estensione.
Per esporre un hook sincrono:
Aggiungi un parametro all'estensione che consenta agli utenti di configurarla
con l'URL della loro funzione Cloud personalizzata. Ad esempio:
-param:PREPROCESSING_FUNCTIONlabel:Pre-processing function URLdescription:>
An HTTPS callable function that will be called to transform the input databefore it is processed by this function.type:stringexample:https://us-west1-my-project-id.cloudfunctions.net/preprocessDatarequired:false
Nel punto dell'estensione in cui vuoi esporre l'hook, chiama la funzione utilizzando il relativo URL. Ad esempio:
constfunctions=require('firebase-functions/v1');constfetch=require('node-fetch');constpreprocessFunctionURL=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{awaitfetch(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.// ...});
Documenta tutti gli hook che rendi disponibili nel file PREINSTALL o
POSTINSTALL.
Per ogni hook, documenta quanto segue:
Il suo scopo previsto
Il punto della logica dell'estensione in cui viene eseguita
I relativi input e output previsti
Le condizioni (o le opzioni) per la sua esecuzione
Inoltre, avvisa gli utenti di non eseguire azioni nella funzione hook
che potrebbero attivare la stessa estensione, con conseguente ciclo
infinito.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Mancano le informazioni di cui ho bisogno","missingTheInformationINeed","thumb-down"],["Troppo complicato/troppi passaggi","tooComplicatedTooManySteps","thumb-down"],["Obsoleti","outOfDate","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Problema relativo a esempi/codice","samplesCodeIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-09-06 UTC."],[],[],null,["\u003cbr /\u003e\n\nYou can provide users who install your extension the ability to insert their own\ncustom logic into the execution of your extension. There are two ways to\naccomplish this:\n\n- **Eventarc events**: to give users a way to asynchronously react to\n events, you can publish to Eventarc. Users can deploy event handler\n functions that, for example, send notifications after long-running\n tasks complete, or they can define their own post-processing functions.\n\n- **Synchronous hooks**: to give users a way to add blocking logic to your\n extension, you can add synchronous hooks at predefined points in the\n extension's operation. At these points, you run a user-provider function\n and proceed only after it completes. Pre-processing tasks often fall under\n this category.\n\nAn extension can use either or both methods.\n\nEventarc events\n\nTo publish events from an extension:\n\n1. Declare the event types you will publish in the `extension.yaml` file:\n\n events:\n - type: publisher-id.extension-name.version.event-name\n description: event-description\n - type: publisher-id.extension-name.version.another-event-name\n description: another-event-description\n\n The `type` identifier is made of several dot-delimited fields. The\n [publisher ID](/docs/extensions/publishers/register), extension name, and event name fields are\n required. The version field is recommended. Choose a unique and descriptive\n event name for each event type you publish.\n\n For example, the [`storage-resize-images` extension](https://github.com/firebase/extensions/blob/next/storage-resize-images/extension.yaml)\n declares a single event type: \n\n events:\n - type: firebase.extensions.storage-resize-images.v1.complete\n description: |\n Occurs when image resizing completes. The event will contain further\n details about specific formats and sizes.\n\n Users will be able to choose which events to subscribe to when they\n install the extension.\n2. In your extension functions, import the Eventarc API from the Admin SDK\n and initialize an event channel using the user's installation settings.\n These settings are exposed using the following environment variables:\n\n - `EVENTARC_CHANNEL`: the fully-qualified name of the Eventarc channel to which the user chose to publish events.\n - `EXT_SELECTED_EVENTS`: a comma-separated list of event types the user chose to publish. When you initialize a channel with this value, the Admin SDK automatically filters out events user did not select.\n - `EVENTARC_CLOUD_EVENT_SOURCE`: the Cloud Event source identifier. The Admin SDK automatically passes this value in the `source` field of published events. You typically don't need to explicitly use this variable.\n\n If events weren't enabled at installation, these variables will be\n undefined. You can use this fact to initialize an event channel only when\n events are enabled: \n\n import * as admin from \"firebase-admin\";\n import {getEventarc} from 'firebase-admin/eventarc';\n\n admin.initializeApp();\n\n // Set eventChannel to a newly-initialized channel, or `undefined` if events\n // aren't enabled.\n const eventChannel =\n process.env.EVENTARC_CHANNEL &&\n getEventarc().channel(process.env.EVENTARC_CHANNEL, {\n allowedEventTypes: process.env.EXT_SELECTED_EVENTS,\n });\n\n3. Publish events to the channel at the points in your extension you want to\n expose to users. For example:\n\n // If events are enabled, publish a `complete` event to the configured\n // channel.\n eventChannel && eventChannel.publish({\n type: 'firebase.extensions.storage-resize-images.v1.complete',\n subject: filename, // the name of the original file\n data: {\n // ...\n }\n });\n\n4. Document the events you publish, in either the PREINSTALL or POSTINSTALL\n file.\n\n For each event, document the following:\n - Its intended purpose\n - The point in your extension's logic it runs\n - The output data it includes\n - The conditions for its execution\n\n Additionally, warn users not to perform any actions in their event\n handlers that might trigger the same extension, resulting in an infinite\n loop.\n\nWhen you publish events from an extension, users can deploy event handlers\nto respond with custom logic.\n\nFor example, the following example deletes the original image after it has been\nresized. Note that this example handler makes use of the `subject` property of\nthe event, which in this case is the image's original filename. \n\n exports.onimageresized = onCustomEventPublished(\n \"firebase.extensions.storage-resize-images.v1.complete\",\n (event) =\u003e {\n logger.info(\"Received image resize completed event\", event);\n // For example, delete the original.\n return admin.storage()\n .bucket(\"my-project.firebasestorage.app\")\n .file(event.subject)\n .delete();\n });\n\nSee [Custom event triggers](/docs/functions/custom-events#handle-events) for more\ninformation.\n\nExample\n\nThe official [Resize Images extension](https://github.com/firebase/extensions/tree/next/storage-resize-images)\nprovides an asynchronous hook by [publishing to Eventarc](https://github.com/firebase/extensions/blob/c29781c7e67c004e2491e4ce3c43b25b05bd3de6/storage-resize-images/functions/src/index.ts#L109-L117)\nafter resizing an image.\n\nSynchronous hooks\n\nWhen you want to provide users with a hook that must complete successfully\nfor one of your extension functions to operate, use *synchronous hooks*.\n\nA synchronous hook calls a user-defined [HTTPS callable Cloud\nFunction](/docs/functions/http-events) and awaits completion (possibly with a\nreturned value) before continuing. An error in the user-provided function\nresults in an error in the extension function.\n\nTo expose a synchronous hook:\n\n1. Add a parameter to your extension that allows users to configure the\n extension with the URL to their custom Cloud Function. For example:\n\n - param: PREPROCESSING_FUNCTION\n label: Pre-processing function URL\n description: \u003e\n An HTTPS callable function that will be called to transform the input data\n before it is processed by this function.\n type: string\n example: https://us-west1-my-project-id.cloudfunctions.net/preprocessData\n required: false\n\n2. At the point in your extension where you want to expose the hook, call the\n function using its URL. For example:\n\n const functions = require('firebase-functions/v1');\n const fetch = require('node-fetch');\n\n const preprocessFunctionURL = process.env.PREPROCESSING_FUNCTION;\n\n exports.yourFunctionName = functions.firestore.document(\"collection/{doc_id}\")\n .onWrite((change, context) =\u003e {\n // PREPROCESSING_FUNCTION hook begins here.\n // If a preprocessing function is defined, call it before continuing.\n if (preprocessFunctionURL) {\n try {\n await fetch(preprocessFunctionURL); // Could also be a POST request if you want to send data.\n } catch (e) {\n // Preprocessing failure causes the function to fail.\n functions.logger.error(\"Preprocessor error:\", e);\n return;\n }\n }\n // End of PREPROCESSING_FUNCTION hook.\n\n // Main function logic follows.\n // ...\n });\n\n3. Document any hooks you make available in either the PREINSTALL or\n POSTINSTALL file.\n\n For each hook, document the following:\n - Its intended purpose\n - The point in your extension's logic it runs\n - Its expected inputs and outputs\n - The conditions (or options) for its execution\n\n Additionally, warn users not to perform any actions in the hook\n function that might trigger the same extension, resulting in an infinite\n loop.\n\nExample\n\nThe [Algolia Search extension](https://github.com/algolia/firestore-algolia-search/)\nprovides a synchronous hook to [call a user-supplied transform function](https://github.com/algolia/firestore-algolia-search/blob/34592d513eac22691d76917874a6466032976f67/functions/src/transform.ts)\nprior to writing to Algolia."]]