Restez organisé à l'aide des collections
Enregistrez et classez les contenus selon vos préférences.
Vous pouvez permettre aux utilisateurs qui installent votre extension d'insérer leur propre logique personnalisée dans l'exécution de votre extension. Pour ce faire, deux méthodes sont possibles :
Événements Eventarc : pour permettre aux utilisateurs de réagir de manière asynchrone aux événements, vous pouvez publier sur Eventarc. Les utilisateurs peuvent déployer des fonctions de gestionnaire d'événements qui, par exemple, envoient des notifications une fois les tâches de longue durée terminées, ou ils peuvent définir leurs propres fonctions de post-traitement.
Crochets synchrones : pour permettre aux utilisateurs d'ajouter une logique de blocage à votre extension, vous pouvez ajouter des crochets synchrones à des points prédéfinis du fonctionnement de l'extension. À ces points, vous exécutez une fonction de fournisseur d'utilisateur et ne poursuivez que lorsqu'elle est terminée. Les tâches de prétraitement entrent souvent dans cette catégorie.
Une extension peut utiliser l'une ou l'autre de ces méthodes, ou les deux.
Événements Eventarc
Pour publier des événements à partir d'une extension :
Déclarez les types d'événements que vous allez publier dans le fichier extension.yaml :
L'identifiant type est composé de plusieurs champs séparés par des points. Les champs ID d'éditeur, nom de l'extension et nom de l'événement sont obligatoires. Le champ "version" est recommandé. Choisissez un nom d'événement unique et descriptif pour chaque type d'événement que vous publiez.
events:-type:firebase.extensions.storage-resize-images.v1.completedescription:|Occurs when image resizing completes. The event will contain furtherdetails about specific formats and sizes.
Les utilisateurs pourront choisir les événements auxquels s'abonner lorsqu'ils installeront l'extension.
Dans les fonctions d'extension, importez l'API Eventarc à partir de Admin SDK et initialisez un canal d'événements à l'aide des paramètres d'installation de l'utilisateur.
Ces paramètres sont exposés à l'aide des variables d'environnement suivantes :
EVENTARC_CHANNEL : nom complet du canal Eventarc sur lequel l'utilisateur a choisi de publier des événements.
EXT_SELECTED_EVENTS : liste des types d'événements que l'utilisateur a choisi de publier, séparés par une virgule. Lorsque vous initialisez un canal avec cette valeur, le SDK Admin filtre automatiquement les événements que l'utilisateur n'a pas sélectionnés.
EVENTARC_CLOUD_EVENT_SOURCE : identifiant de la source Cloud Events. Le SDK Admin transmet automatiquement cette valeur dans le champ source des événements publiés. Vous n'avez généralement pas besoin d'utiliser explicitement cette variable.
Si les événements n'ont pas été activés lors de l'installation, ces variables seront indéfinies. Vous pouvez utiliser ce fait pour initialiser un canal d'événements uniquement lorsque les événements sont activés :
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,});
Publiez des événements sur la chaîne aux points de votre extension que vous souhaitez exposer aux utilisateurs. Exemple :
// 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:{// ...}});
Documentez les événements que vous publiez dans le fichier PREINSTALL ou POSTINSTALL.
Pour chaque événement, documentez les points suivants :
sa finalité prévue ;
Le point de la logique de votre extension à partir duquel elle s'exécute
les données de sortie qu'il inclut ;
les conditions de son exécution ;
Avertissez également les utilisateurs de ne pas effectuer d'actions dans leurs gestionnaires d'événements qui pourraient déclencher la même extension, ce qui entraînerait une boucle infinie.
Lorsque vous publiez des événements à partir d'une extension, les utilisateurs peuvent déployer des gestionnaires d'événements pour répondre avec une logique personnalisée.
Par exemple, l'exemple suivant supprime l'image d'origine après son redimensionnement. Notez que ce gestionnaire d'exemple utilise la propriété subject de l'événement, qui correspond dans ce cas au nom de fichier d'origine de l'image.
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();});
Utilisez des crochets synchrones lorsque vous souhaitez fournir aux utilisateurs un crochet qui doit se terminer correctement pour que l'une de vos fonctions d'extension fonctionne.
Un crochet synchrone appelle une fonction Cloud appelable HTTPS définie par l'utilisateur et attend la fin de l'exécution (éventuellement avec une valeur renvoyée) avant de continuer. Une erreur dans la fonction fournie par l'utilisateur entraîne une erreur dans la fonction d'extension.
Pour exposer un crochet synchrone :
Ajoutez un paramètre à votre extension pour permettre aux utilisateurs de la configurer avec l'URL de leur fonction Cloud personnalisée. Exemple :
-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
Au point de votre extension où vous souhaitez exposer le crochet, appelez la fonction à l'aide de son URL. Exemple :
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.// ...});
Documentez tous les hooks que vous mettez à disposition dans le fichier PREINSTALL ou POSTINSTALL.
Pour chaque hook, documentez les points suivants :
sa finalité prévue ;
Le point de la logique de votre extension à partir duquel elle s'exécute
Ses entrées et sorties attendues
les conditions (ou options) de son exécution.
Avertissez également les utilisateurs de ne pas effectuer d'actions dans la fonction de crochet qui pourraient déclencher la même extension, ce qui entraînerait une boucle infinie.
Sauf indication contraire, le contenu de cette page est régi par une licence Creative Commons Attribution 4.0, et les échantillons de code sont régis par une licence Apache 2.0. Pour en savoir plus, consultez les Règles du site Google Developers. Java est une marque déposée d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/09/06 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Il n'y a pas l'information dont j'ai besoin","missingTheInformationINeed","thumb-down"],["Trop compliqué/Trop d'étapes","tooComplicatedTooManySteps","thumb-down"],["Obsolète","outOfDate","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Mauvais exemple/Erreur de code","samplesCodeIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 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."]]