Вы можете предоставить пользователям, которые устанавливают ваше расширение, возможность вставлять свою собственную логику в выполнение вашего расширения. Есть два способа сделать это:
События Eventarc : чтобы дать пользователям возможность асинхронно реагировать на события, вы можете публиковать их в Eventarc. Поль��ователи могут развертывать функции обработчика событий, которые, например, отправляют уведомления после завершения длительных задач, или определять свои собственные функции постобработки.
Синхронные перехватчики : чтобы дать пользователям возможность добавлять логику блокировки в ваше расширение, вы можете добавлять синхронные перехватчики в заранее определенные точки работы расширения. На этом этапе вы запускаете функцию поставщика пользователей и продолжаете работу только после ее завершения. Задачи предварительной обработки часто подпадают под эту категорию.
Расширение может использовать один или оба метода.
События Eventarc
Чтобы опубликовать события из расширения:
Объявите типы событий, которые вы будете публиковать, в файле
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.
Пользователи смогут выбирать, на какие события подписываться при установке расширения.
В функциях расширения импортируйте 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, });
-
Публикуйте события на канале в тех точках вашего расширения, которые вы хотите показать пользователям. Например:
// 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: { // ... } });
Документируйте события, которые вы публикуете, в файле 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 и ожидает завершения (возможно, с возвращаемым значением), прежде чем продолжить. Ошибка в предоставленной пользователем функции приводит к ошибке в функции расширения.
Чтобы открыть синхронный хук:
Добавьте в расширение параметр, который позволит пользователям настраивать расширение с помощью 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
В том месте вашего расширения, где вы хотите использовать перехватчик, вызовите функцию, используя ее 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. // ... });
Задокументируйте все перехватчики, которые вы предоставляете в файле PREINSTALL или POSTINSTALL.
Для каждого крючка задокументируйте следующее:
- Его целевое назначение
- Точка в логике вашего расширения, которую он выполняет
- Ожидаемые входы и результаты
- Условия (или варианты) его исполнения
Кроме того, предупредите пользователей, чтобы они не выполняли в функции перехвата никаких действий, которые могут вызвать одно и то же расширение, что приведет к бесконечному циклу.
Пример
Расширение Algolia Search предоставляет синхронный крючок для вызова предоставленной пользователем функции преобразования перед записью в Algolia.