Добавьте пользовательские перехватчики в расширение

Вы можете предоставить пользователям, которые устанавливают ваше расширение, возможность вставлять свою собственную логику в выполнение вашего расширения. Есть два способа сделать это:

  • События Eventarc : чтобы дать пользователям возможность асинхронно реагировать на события, вы можете публиковать их в Eventarc. Поль��ователи могут развертывать функции обработчика событий, которые, например, отправляют уведомления после завершения длительных задач, или определять свои собственные функции постобработки.

  • Синхронные перехватчики : чтобы дать пользователям возможность добавлять логику блокировки в ваше расширение, вы можете добавлять синхронные перехватчики в заранее определенные точки работы расширения. На этом этапе вы запускаете функцию поставщика пользователей и продолжаете работу только после ее завершения. Задачи предварительной обработки часто подпадают под эту категорию.

Расширение может использовать один или оба метода.

События Eventarc

Чтобы опубликовать события из расширения:

  1. Объявите типы событий, которые вы будете публиковать, в файле 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
    

    Идентификатор type состоит из нескольких полей, разделенных точками. Поля «Идентификатор издателя» , «Название расширения» и «Название события» являются обязательными. Поле версии рекомендуется. Выберите уникальное и описательное название мероприятия для каждого типа публикуемого вами мероприятия.

    Например, расширение storage-resize-images объявляет один тип события:

    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.
    

    Пользователи смогут выбирать, на какие события подписываться при установке расширения.

  2. В функциях расширения импортируйте API Eventarc из Admin SDK и инициализируйте канал событий, используя настройки установки пользователя. Эти параметры предоставляются с помощью следующих переменных среды:

    • EVENTARC_CHANNEL : полное имя канала Eventarc, на котором пользователь решил публиковать события.
    • EXT_SELECTED_EVENTS : список типов событий, разделенных запятыми, которые пользователь выбрал для публикации. Когда вы инициализируете канал с этим значением, Admin SDK автоматически отфильтровывает события, которые пользователь не выбрал.
    • EVENTARC_CLOUD_EVENT_SOURCE : идентификатор источника облачных событий. Admin SDK автоматически передает это значение в поле source опубликованных событий. Обычно вам не нужно явно использовать эту переменную.

    Если события не были включены при установке, эти переменные будут неопределенными. Вы можете использовать этот факт для инициализ��ции ка��ала событий только тогда, когда события включены:

    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. Публикуйте события на канале в тех точках вашего расширения, которые вы хотите показать пользователям. Например:

    // 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. Документируйте события, которые вы публикуете, в файле PREINSTALL или POSTINSTALL.

    По каждому событию документируйте следующее:

    • Его целевое назначение
    • Точка в логике вашего расширения, которую он выполняет
    • Выходные данные, которые он включает в себя
    • Условия его исполнения

    Кроме того, предупредите пользователей, чтобы они не выполняли в своих обработчиках событий никаких действий, которые могут вызвать одно и то же расширение, что приведет к бесконечному циклу.

Когда вы публикуете события из расширения, пользователи могут развертывать обработчики событий для реагирования с помощью собственной логики.

Например, в следующем примере удаляется исходное изображение после изменения его размера. Обратите внимание, что в этом примере обработчика используется свойство subject события, которым в данном случае является исходное имя файла изображения.

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();
    });

Дополнительные сведения см. в разделе Пользовательские триггеры событий .

Пример

Официальное расширение Resize Images обеспечивает асинхронную перехватку путем публикации в Eventarc после изменения размера изображения.

Синхронные крючки

Если вы хотите предоставить пользователям перехватчик, который должен успешно завершиться для работы одной из ваших функций расширения, используйте синхронные перехватчики .

Синхронный перехват вызывает определяемую пользователем облачную функцию HTTPS и ожидает завершения (возможно, с возвращаемым значением), прежде чем продолжить. Ошибка в предоставленной пользователем функции приводит к ошибке в функции расширения.

Чтобы открыть синхронный хук:

  1. Добавьте в расширение параметр, который позволит пользователям настраивать расширение с помощью URL-адреса своей пользовательской облачной функции. Например:

    - 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. В том месте вашего расширения, где вы хотите использовать перехватчик, вызовите функцию, используя ее URL-адрес. Например:

    const functions = require('firebase-functions');
    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. Задокументируйте все перехватчики, которые вы предоставляете в файле PREINSTALL или POSTINSTALL.

    Для каждого крючка задокументируйте следующее:

    • Его целевое назначение
    • Точка в логике вашего расширения, которую он выполняет
    • Ожидаемые входы и результаты
    • Условия (или варианты) его исполнения

    Кроме того, предупредите пользователей, чтобы они не выполняли в функции перехвата никаких действий, которые могут вызвать одно и то же расширение, что приведет к бесконечному циклу.

Пример

Расширение Algolia Search предоставляет синхронный крючок для вызова предоставленной пользователем функции преобразования перед записью в Algolia.