Ajouter des hooks utilisateur à une extension

Vous pouvez permettre aux utilisateurs qui installent votre extension d'insérer leurs propres une logique personnalisée dans l'exécution de votre extension. Il existe deux façons cela:

  • Événements Eventarc : pour permettre aux utilisateurs de réagir de manière asynchrone aux événements, vous pouvez publier des événements dans 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.

  • Hooks synchrones : pour permettre aux utilisateurs d'ajouter une logique de blocage à votre extension, vous pouvez ajouter des hooks synchrones à des points prédéfinis de l'exécution de l'extension. À ce stade, vous exécutez une fonction de fournisseur d'utilisateur et ne continuez qu'une fois l'opération terminée. Les tâches de prétraitement sont souvent 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:

  1. Déclarez les types d'événements que vous publierez dans le fichier 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
    

    L'identifiant type est composé de plusieurs champs délimités par un point. Les champs ID de l'éditeur, nom de l'extension et nom de l'événement sont obligatoires. Il est recommandé d'utiliser le champ de version. Choisissez un nom unique et descriptif nom d'événement pour chaque type d'événement que vous publiez.

    Par exemple, l'extension storage-resize-images déclare un seul type d'événement :

    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.
    

    Les utilisateurs pourront choisir les événements auxquels s'abonner lorsqu'ils installer l'extension.

  2. Dans vos 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 à utiliser que l'utilisateur a choisi de publier.
    • EXT_SELECTED_EVENTS: liste des types d'événements séparés par une virgule que l'utilisateur choisi de publier. 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 de l'événement cloud. La Le SDK Admin transmet automatiquement cette valeur dans le champ source de les événements publiés. Généralement, vous n'avez pas besoin d'utiliser .

    Si les événements n'ont pas été activés lors de l'installation, ces variables seront non défini. Vous ne pouvez utiliser ce facteur pour initialiser un canal d'événement que lorsque les événements suivants sont activés:

    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,
      });
    
  3. Publiez des événements sur le canal aux points de votre extension que vous souhaitez présenter 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 file
        data: {
          // ...
        }
    });
    
  4. Documentez les événements que vous publiez, à l'aide de la méthode PREINSTALL ou POSTINSTALL .

    Pour chaque événement, documentez les points suivants :

    • Sa finalité
    • Le point de la logique de votre extension qu'elle exécute
    • Les données de sortie qu'il inclut
    • ses conditions d'exécution.

    De plus, avertir les utilisateurs de ne pas effectuer d'actions dans leur événement qui peuvent déclencher la même extension, ce qui génère un nombre infini en boucle.

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 sa redimensionnement. Notez que cet exemple de gestionnaire utilise la propriété subject de l'événement qui, dans ce cas, est le 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.
      return admin.storage()
          .bucket("my-project.appspot.com")
          .file(event.subject)
          .delete();
    });

Pour en savoir plus, consultez Déclencheurs d'événements personnalisés des informations.

Exemple

L'extension officielle de redimensionnement des images fournit un crochet asynchrone en publiant dans Eventarc après avoir redimensionné une image.

Hooks synchrones

Lorsque vous souhaitez fournir aux utilisateurs un hook qui doit aboutir pour qu'une de vos fonctions d'extension fonctionne, utilisez des hooks synchrones.

Un hook synchrone appelle un service HTTPS appelable Fonction et attend la fin de l'opération (avec éventuellement un (valeur renvoyée) avant de continuer. Erreur dans la fonction fournie par l'utilisateur entraîne une erreur dans la fonction d'extension.

Pour exposer un hook synchrone :

  1. Ajoutez à votre extension un paramètre permettant aux utilisateurs de configurer le par l'URL de sa fonction Cloud personnalisée. Exemple :

    - 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
    
  2. À l'endroit de votre extension où vous souhaitez exposer l'accroche, appelez la méthode à l'aide de son URL. Exemple :

    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.
          // ...
        });
    
  3. Documentez tous les hooks que vous mettez à disposition dans la préinstallation ou POSTINSTALL.

    Pour chaque hook, documentez les points suivants :

    • Son objectif
    • Le point de la logique de votre extension qu'elle exécute
    • Ses entrées et sorties attendues
    • Les conditions (ou options) de son exécution

    De plus, avertir les utilisateurs de ne pas effectuer d'actions dans le hook qui peut déclencher la même extension, ce qui donne un résultat infini en boucle.

Exemple

L'extension de recherche Algolia fournit un crochet synchrone pour appeler une fonction de transformation fournie par l'utilisateur avant d'écrire dans Algolia.