1. Прежде чем начать
Расширение Firebase выполняет определенную задачу или набор задач в ответ на HTTP-запросы или запуск событий из других продуктов Firebase и Google, таких как Firebase Cloud Messaging, Cloud Firestore или Pub/Sub.
Что вы построите
В этой лабораторной работе вы создадите расширение Firebase для геохеширования . После развертывания ваше расширение будет преобразовывать координаты X и Y в геохеш-данные в ответ на события Firestore или посредством вызовов вызываемых функций. Это можно использовать как альтернативу внедрению библиотеки Geofire на всех целевых платформах для хранения данных, экономя время.
Чему вы научитесь
- Как взять существующий код Cloud Functions и превратить его в распространяемое расширение Firebase
- Как настроить файл
extension.yaml
- Как хранить конфиденциальные строки (ключи API) в расширении
- Как разрешить разработчикам расширения настраивать его под свои нужды
- Как протестировать и развернуть расширение
Что вам понадобится
- Firebase CLI (установка и вход)
- Учетная запись Google, например учетная запись Gmail
- Node.js и
npm
- Ваша любимая среда разработки
2. Настройте
Получить код
Всё необходимое для этого расширения есть в репозитории GitHub. Чтобы начать работу, скачайте код и откройте его в вашей любимой среде разработки.
- Распакуйте загруженный zip-файл.
- Чтобы установить необходимые зависимости, откройте терминал в каталоге
functions
и выполните командуnpm install
.
Настройте Firebase
В этой лабораторной работе настоятельно рекомендуется использовать эмуляторы Firebase. Если вы хотите попробовать разработку расширений для настоящего проекта Firebase, см. раздел «Создание проекта Firebase» . В этой лабораторной работе используются функции Cloud Functions, поэтому, если вы используете настоящий проект Firebase вместо эмуляторов, вам необходимо перейти на тарифный план Blaze .
Хотите пропустить?
Вы можете скачать готовую версию практического кода. Если вы застряли на этом этапе или хотите увидеть, как выглядит готовое расширение, загляните в ветку codelab-end
репозитория GitHub или скачайте готовый ZIP-архив.
3. Проверьте код.
- Откройте файл
index.ts
из zip-архива. Обратите внимание, что он содержит два объявления облачных функций.
Что делают эти функции?
Эти демонстрационные функции используются для геохеширования. Они принимают пару координат и преобразуют их в формат, оптимизированный для геозапросов в Firestore. Эти функции имитируют использование API-вызова, что позволяет вам узнать больше об обработке конфиденциальных типов данных в расширениях. Подробнее см. в документации по выполнению геозапросов к данным в Firestore .
Константы функций
Константы объявляются в начале файла index.ts
. Некоторые из этих констант упоминаются в триггерах, определённых в расширении.
индекс.ts
import {firestore} from "firebase-functions";
import {initializeApp} from "firebase-admin/app";
import {GeoHashService, ResultStatusCode} from "./fake-geohash-service";
import {onCall} from "firebase-functions/v1/https";
import {fieldValueExists} from "./utils";
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";
initializeApp();
const service = new GeoHashService(apiKey);
Триггер Firestore
Первая функция в файле index.ts
выглядит так:
индекс.ts
export const locationUpdate = firestore.document(documentPath)
.onWrite((change) => {
// item deleted
if (change.after == null) {
return 0;
}
// double check that both values exist for computation
if (
!fieldValueExists(change.after.data(), xField) ||
!fieldValueExists(change.after.data(), yField)
) {
return 0;
}
const x: number = change.after.data()![xField];
const y: number = change.after.data()![yField];
const hash = service.convertToHash(x, y);
// This is to check whether the hash value has changed. If
// it hasn't, you don't want to write to the document again as it
// would create a recursive write loop.
if (fieldValueExists(change.after.data(), outputField)
&& change.after.data()![outputField] == hash) {
return 0;
}
return change.after.ref
.update(
{
[outputField]: hash.hash,
}
);
});
Эта функция представляет собой триггер Firestore . Когда в базе данных происходит запись, функция реагирует на это событие, выполняя поиск полей xv
и yv
, и, если оба поля существуют, вычисляет геохеш и записывает выходные данные в указанное расположение выходных данных документа. Входной документ определяется константой users/{uid}
, что означает, что функция считывает каждый документ, записанный в коллекцию users/
и затем обрабатывает геохеш для этих документов. Затем она выводит хеш в поле хеширования в том же документе.
Вызываемые функции
Следующая функция в файле index.ts
выглядит так:
индекс.ts
export const callableHash = onCall((data, context) => {
if (context.auth == undefined) {
return {error: "Only authorized users are allowed to call this endpoint"};
}
const x = data[xField];
const y = data[yField];
if (x == undefined || y == undefined) {
return {error: "Either x or y parameter was not declared"};
}
const result = service.convertToHash(x, y);
if (result.status != ResultStatusCode.ok) {
return {error: `Something went wrong ${result.message}`};
}
return {result: result.hash};
});
Обратите внимание на функцию onCall
. Она указывает, что эта функция является вызываемой функцией , которую можно вызвать из кода клиентского приложения. Эта вызываемая функция принимает параметры x
и y
и возвращает геохеш. Хотя эта функция не будет вызываться напрямую в этой лабораторной работе, она включена сюда как пример настройки в расширении Firebase.
4. Настройте файл extension.yaml.
Теперь, когда вы знаете, что делает код Cloud Functions в вашем расширении, вы готовы упаковать его для распространения. Каждое расширение Firebase поставляется с файлом extension.yaml
, описывающим, что делает расширение и как оно себя ведет.
Файл extension.yaml
требует некоторых начальных метаданных о вашем расширении. Каждый из следующих шагов поможет вам понять значение всех полей и зачем они вам нужны.
- Создайте файл
extension.yaml
в корневом каталоге проекта, который вы скачали ранее. Начните с добавления следующего:
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
Имя расширения используется в качестве основы для идентификатора экземпляра расширения (пользователи могут установить несколько экземпляров расширения, каждый со своим идентификатором). Затем Firebase генерирует имя учётных записей служб расширения и ресурсов, специфичных для расширения, используя этот идентификатор экземпляра. Номер версии указывает версию вашего расширения. Он должен соответствовать семантическому версионированию , и его необходимо обновлять при каждом изменении функциональности расширения. Версия спецификации расширения используется для определения спецификации расширений Firebase, которой необходимо следовать; в данном случае используется v1beta
.
- Добавьте в файл YAML некоторые удобные для пользователя сведения:
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
Отображаемое имя — это удобное представление имени вашего расширения при взаимодействии с ним разработчиков. Описание содержит краткий обзор функций расширения. После развертывания расширения на extensions.dev оно выглядит примерно так:
- Укажите лицензию на код в вашем расширении.
...
license: Apache-2.0 # The license you want for the extension
- Укажите, кто написал расширение и требуется ли взимание платы за его установку:
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
Раздел author
используется для того, чтобы ваши пользователи знали, к кому обратиться в случае возникновения проблем с расширением или если им нужна дополнительная информация о нем. billingRequired
— обязательный параметр, и ему должно быть присвоено значение true
поскольку все расширения используют Cloud Functions, для которого требуется план Blaze.
Это минимальное количество полей, необходимых для идентификации расширения в файле extension.yaml
. Подробнее о других идентифицирующих данных, которые можно указать в расширении, см. в документации .
5. Преобразуйте код облачных функций в ресурс расширений.
Ресурс расширения — это элемент, который Firebase создаёт в проекте во время установки расширения. Расширение становится владельцем этих ресурсов и имеет специальную учётную запись службы, которая ими управляет. В данном проекте этими ресурсами являются облачные функции, которые необходимо определить в файле extension.yaml
, поскольку расширение не создаёт ресурсы автоматически из кода в папке функций. Если ваши облачные функции не объявлены явно как ресурс, их невозможно развернуть при развёртывании расширения.
Место развертывания, определяемое пользователем
- Позвольте пользователю указать место для развертывания этого расширения и решить, будет ли лучше разместить расширение ближе к конечным пользователям или ближе к базе данных. В файле
extension.yaml
включите возможность выбора местоположения.
расширение.yaml
Теперь вы готовы написать конфигурацию для функционального ресурса.
- В файле
extension.yaml
создайте объект ресурса для функцииlocationUpdate
. Добавьте в файлextension.yaml
следующее:
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
name
определяется как имя функции, определенное в файле index.ts
проекта. Вы указываете type
развертываемой функции, который на данный момент всегда должен быть firebaseextensions.v1beta.function
. Затем вы определяете properties
этой функции. Первое свойство, которое вы определяете, — это eventTrigger
, связанный с этой функцией. Чтобы отразить то, что в настоящее время поддерживает расширение, вы используете eventType
из providers/cloud.firestore/eventTypes/document.write
, который находится в документации Write Cloud Functions для вашего расширения . Вы определяете resource
как расположение документов. Поскольку вашей текущей целью является отражение того, что существует в коде, путь к документу прослушивает users/{uid}
, а расположение базы данных по умолчанию предшествует ему.
- Расширению требуются права на чтение и запись в базу данных Firestore. В самом конце файла
extension.yaml
укажите роли IAM, к которым расширение должно иметь доступ для работы с базой данных в проекте Firebase разработчика.
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Роль datastore.user
входит в список поддерживаемых IAM-ролей для расширений . Поскольку расширение будет выполнять чтение и запись, роль datastore.user
отлично подходит.
- Необходимо также добавить вызываемую функцию. В файле
extension.yaml
создайте новый ресурс в свойстве resources. Эти свойства относятся только к вызываемой функции:
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
Хотя предыдущий ресурс использовал eventTrigger
, здесь вы используете httpsTrigger
, который охватывает как вызываемые функции, так и функции HTTPS.
Проверка кода
Потребовалось много настроек, чтобы ваш extension.yaml
соответствовал всему коду в файле index.ts
. Вот как должен выглядеть готовый файл extension.yaml
на данный момент:
расширение.yaml
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.
license: Apache-2.0 # The license you want for the extension
author:
authorName: Sparky
url: https://github.com/Firebase
billingRequired: true
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Проверка статуса
На этом этапе у вас уже настроены начальные функциональные части расширения, и вы можете опробовать их с помощью эмуляторов Firebase!
- Если вы еще этого не сделали, вызовите
npm run build
в папке функций загруженного проекта расширений. - Создайте новый каталог в вашей хост-системе и подключите этот каталог к вашему проекту Firebase с помощью
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
This command creates a `firebase.json` file in the directory. In the following steps, you push the configuration specified in this file to Firebase.
- Из того же каталога выполните команду
firebase ext:install
. Замените/path/to/extension
на абсолютный путь к каталогу, содержащему файлextension.yaml
.
firebase ext:install /path/to/extension
This command does two things:
- Он предлагает вам указать конфигурацию для экземпляра расширения и создает файл
*.env
, содержащий информацию о конфигурации для экземпляра. - Он добавляет экземпляр расширения в раздел
extensions
файлаfirebase.json
. Это служит сопоставлением идентификатора экземпляра с версией расширения. - Поскольку вы развертываете проект локально, вы можете указать, что хотите использовать локальный файл вместо Google Cloud Secret Manager.
- Запустите эмуляторы Firebase с новой конфигурацией:
firebase emulators:start
- После запуска
emulators:start
перейдите на вкладку Firestore в веб-представлении эмуляторов. - Добавьте документ в коллекцию
users
с полем номераxv
и полем номераyv
.
- Если установка расширения прошла успешно, оно создаст в документе новое поле, называемое
hash
.
Уборка во избежание конфликтов
- После завершения тестирования удалите расширение, так как вы собираетесь обновить код расширения и не хотите в дальнейшем конфликтовать с текущим расширением.
Расширения позволяют устанавливать несколько версий одного и того же расширения одновременно, поэтому при удалении вы гарантируете отсутствие конфликтов с ранее установленным расширением.
firebase ext:uninstall geohash-ext
Текущее решение работает, но, как упоминалось в начале проекта, API-ключ жёстко прописан в коде для имитации взаимодействия с сервисом. Как использовать API-ключ конечного пользователя вместо изначально предоставленного? Читайте дальше, чтобы узнать больше.
6. Сделайте расширение настраиваемым пользователем.
На этом этапе работы над кодовой лабораторией у вас есть расширение, настроенное для использования с уже написанными вами функциями, но что, если пользователь захочет использовать широту и долготу вместо y и x для полей, указывающих местоположение на декартовой плоскости? Кроме того, как заставить конечного пользователя предоставить собственный ключ API, а не использовать предоставленный? Вы можете быстро превысить квоту для этого API. В этом случае вы настраиваете и используете параметры.
Определите основные параметры в файле extension.yaml
Начнем с преобразования элементов, для которых у разработчиков потенциально может быть своя конфигурация. Первыми будут параметры XFIELD
и YFIELD
.
- В файл
extension.yaml
добавьте следующий код, использующий параметры полейXFIELD
иYFIELD
. Эти параметры находятся внутри ранее определенного свойства YAMLparams
:
расширение.yaml
params:
- param: XFIELD
label: The X Field Name
description: >-
The X Field is also known as the **longitude** value. What does
your Firestore instance refer to as the X value or the longitude
value. If no value is specified, the extension searches for
field 'xv'.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: xv
required: false
immutable: false
example: xv
- param: YFIELD
label: The Y Field Name
description: >-
The Y Field is also known as the **latitude** value. What does
your Firestore instance refer to as the Y value or the latitude
value. If no value is specified, the extension searches for
field 'yv'.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: yv
required: false
immutable: false
example: yv
- Параметр param именует параметр так, чтобы его было видно вам, создателю расширения. Используйте это значение позже при указании значений параметров.
- label — это понятный человеку идентификатор, позволяющий разработчику понять, что делает параметр.
- Описание содержит подробное описание значения. Поскольку поддерживается разметка, оно может ссылаться на дополнительную документацию или выделять слова, которые могут быть важны для разработчика.
- Тип определяет механизм ввода, с помощью которого пользователь может задать значение параметра. Существует множество типов, включая
string
,select
,multiSelect
,selectResource
иsecret
. Подробнее о каждом из этих параметров см. в документации . - validationRegex ограничивает запись разработчика определенным значением регулярного выражения (в примере оно основано на простых рекомендациях по именам полей, которые можно найти здесь ); и если это не удается...
- validationErrorMessage оповещает разработчика о значении ошибки.
- default — это то значение, которое было бы, если бы разработчик не ввел никакого текста.
- required означает, что разработчику не требуется вводить какой-либо текст.
- Неизменяемость позволяет разработчику обновлять это расширение и изменять это значение. В этом случае разработчик должен иметь возможность изменять имена полей по мере изменения своих требований.
- пример дает представление о том, как могут выглядеть допустимые входные данные.
Это было очень сложно понять!
- Перед добавлением специального параметра в файл
extension.yaml
необходимо добавить еще три параметра.
- param: INPUTPATH
label: The input document to listen to for changes
description: >-
This is the document where you write an x and y value to. Once
that document has received a value, it notifies the extension to
calculate a geohash and store that in an output document in a certain
field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
type: string
validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
validationErrorMessage: >-
This must point to a document path, not a collection path from the root
of the database. It must also not start or end with a '/' character.
required: true
immutable: false
example: users/{uid}
- param: OUTPUTFIELD
label: Geohash field
description: >-
This specifies the field in the output document to store the geohash in.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
required: false
default: hash
immutable: false
example: hash
Определить чувствительные параметры
Теперь вам нужно управлять ключом API, который указывает пользователь. Это конфиденциальная строка, которую не следует хранить в открытом виде в функции. Вместо этого сохраните это значение в Cloud Secret Manager . Это специальное место в облаке, где хранятся зашифрованные секреты, предотвращая их случайную утечку. Это требует от разработчика оплаты за использование этого сервиса, но добавляет дополнительный уровень безопасности к его ключам API и потенциально ограничивает мошенническую деятельность. Пользовательская документация предупреждает разработчика о том, что это платный сервис, чтобы избежать сюрпризов при выставлении счетов. В целом, использование аналогично использованию других строковых ресурсов, упомянутых выше. Единственное отличие — тип, который называется secret
.
- В файле
extension.yaml
добавьте следующий код:
расширение.yaml
- param: APIKEY
label: GeohashService API Key
description: >-
Your geohash service API Key. Since this is a demo, and not a real
service, you can use : 1234567890.
type: secret
required: true
immutable: false
Обновите атрибуты resource
для использования параметров
Как упоминалось ранее, ресурс (а не функция) определяет, как наблюдается ресурс, поэтому ресурс locationUpdate
необходимо обновить, чтобы использовать новый параметр.
- В файле
extension.yaml
добавьте следующий код:
расширение.yaml
## Change from this
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}]
## To this
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
Проверьте файл extension.yaml
- Проверьте файл
extension.yaml
. Он должен выглядеть примерно так:
расширение.yaml
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.
license: Apache-2.0 # The license you want to use for the extension
author:
authorName: Sparky
url: https://github.com/Firebase
billingRequired: true
params:
- param: XFIELD
label: The X Field Name
description: >-
The X Field is also known as the **longitude** value. What does
your Firestore instance refer to as the X value or the longitude
value. If you don't provide a value for this field, the extension will use 'xv' as the default value.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: xv
required: false
immutable: false
example: xv
- param: YFIELD
label: The Y Field Name
description: >-
The Y Field is also known as the **latitude** value. What does
your Firestore instance refer to as the Y value or the latitude
Value. If you don't provide a value for this field, the extension will use 'yv' as the default value.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: yv
required: false
immutable: false
example: yv
- param: INPUTPATH
label: The input document to listen to for changes
description: >-
This is the document where you write an x and y value to. Once
that document has been modified, it notifies the extension to
compute a geohash and store that in an output document in a certain
field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
type: string
validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
validationErrorMessage: >-
This must point to a document path, not a collection path from the root
of the database. It must also not start or end with a '/' character.
required: true
immutable: false
example: users/{uid}
- param: OUTPUTFIELD
label: Geohash field
description: >-
This specifies the field in the output document to store the geohash in.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
required: false
default: hash
immutable: false
example: hash
- param: APIKEY
label: GeohashService API Key
description: >-
Your geohash service API Key. Since this is a demo, and not a real
service, you can use : 1234567890.
type: secret
required: true
immutable: false
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Параметры доступа в коде
Теперь, когда все параметры настроены в файле extension.yaml
, добавьте их в файл index.ts
.
- В файле
index.ts
замените значения по умолчанию наprocess.env.PARAMETER_NAME
, который извлекает соответствующие значения параметров и заполняет их в коде функции, развернутом в проекте Firebase разработчика.
индекс.ts
// Replace this:
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";
// with this:
const documentPath = process.env.INPUTPATH!; // this value is ignored since its read from the resource
const xField = process.env.XFIELD!;
const yField = process.env.YFIELD!;
const apiKey = process.env.APIKEY!;
const outputField = process.env.OUTPUTFIELD!;
Обычно требуется выполнять проверки на null значений переменных окружения, но в данном случае вы уверены, что значения параметров скопированы корректно. Теперь код настроен на работу с параметрами расширения.
7. Создайте пользовательскую документацию
Перед тестированием кода на эмуляторах или в магазине расширений Firebase необходимо задокументировать расширение, чтобы разработчики знали, что они получают при его использовании.
- Начните с создания файла
PREINSTALL.md
, который используется для описания функциональности, любых предварительных условий для установки и возможных последствий для выставления счетов.
PREINSTALL.md
Use this extension to automatically convert documents with a latitude and
longitude to a geohash in your database. Additionally, this extension includes a callable function that allows users to make one-time calls
to convert an x,y coordinate into a geohash.
Geohashing is supported for latitudes between 90 and -90 and longitudes
between 180 and -180.
#### Third Party API Key
This extension uses a fictitious third-party API for calculating the
geohash. You need to supply your own API keys. (Since it's fictitious,
you can use 1234567890 as an API key).
#### Additional setup
Before installing this extension, make sure that you've [set up a Cloud
Firestore database](https://firebase.google.com/docs/firestore/quickstart) in your Firebase project.
After installing this extension, you'll need to:
- Update your client code to point to the callable geohash function if you
want to perform arbitrary geohashes.
Detailed information for these post-installation tasks are provided after
you install this extension.
#### Billing
To install an extension, your project must be on the [Blaze (pay as you
go) plan](https://firebase.google.com/pricing)
- This extension uses other Firebase and Google Cloud Platform services,
which have associated charges if you exceed the service's no-cost tier:
- Cloud Firestore
- Cloud Functions (Node.js 16+ runtime. [See
FAQs](https://firebase.google.com/support/faq#extensions-pricing))
- [Cloud Secret Manager](https://cloud.google.com/secret-manager/pricing)
- Чтобы сэкономить время на написание
README.md
для этого проекта, воспользуйтесь удобным методом:
firebase ext:info . --markdown > README.md
Он объединяет содержимое файла PREINSTALL.md
и дополнительную информацию о вашем расширении из файла extension.yaml
.
Наконец, сообщите разработчику расширения дополнительную информацию о только что установленном расширении. После завершения установки разработчик может получить дополнительные инструкции и информацию, а также подробные инструкции по выполнению последующих задач, например, по настройке клиентского кода, здесь.
- Создайте файл
POSTINSTALL.md
, а затем включите в него следующую информацию после установки:
POSTINSTALL.md
Congratulations on installing the geohash extension!
#### Function information
* **Firestore Trigger** - ${function:locationUpdate.name} was installed
and is invoked when both an x field (${param:XFIELD}) and y field
(${param:YFIELD}) contain a value.
* **Callable Trigger** - ${function:callableHash.name} was installed and
can be invoked by writing the following client code:
```javascript
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const geoHash = httpsCallable(functions, '${function:callableHash.name}');
geoHash({ ${param:XFIELD}: -122.0840, ${param:YFIELD}: 37.4221 })
.then((result) => {
// Read result of the Cloud Function.
/** @type {any} */
const data = result.data;
const error = data.error;
if (error != null) {
console.error(`callable error : ${error}`);
}
const result = data.result;
console.log(result);
});
Мониторинг
Лучше всего отслеживать активность установленного расширения, включая проверки его работоспособности, использования и журналов.
The output rendering looks something like this when it's deployed:
<img src="img/82b54a5c6ca34b3c.png" alt="A preview of the latitude and longitude geohash converter extension in the firebase console" width="957.00" />
## Test the extension with the full configuration
Duration: 03:00
It's time to make sure that the user-configurable extension is working the way it is intended.
* Change into the functions folder and ensure that the latest compiled version of the extensions exists. In the extensions project functions directory, call:
```console
npm run build
Это перекомпилирует функции, чтобы новейший исходный код был готов к развертыванию вместе с расширением при его развертывании на эмуляторе или непосредственно в Firebase.
Затем создайте новый каталог для тестирования расширения. Поскольку расширение разработано на основе существующих функций, не тестируйте его из папки, в которой оно было настроено, так как в ней также будут развёрнуты функции и правила Firebase.
Установка и тестирование с помощью эмуляторов Firebase
- Создайте новый каталог в вашей хост-системе и подключите этот каталог к вашему проекту Firebase с помощью
firebase init
.
mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Из этого каталога выполните
firebase ext:install
для установки расширения. Замените/path/to/extension
на абсолютный путь к каталогу, содержащему файлextension.yaml
. Это запустит процесс установки расширения и создаст файл.env
с вашими конфигурациями перед их отправкой в Firebase или на эмуляторы.
firebase ext:install /path/to/extension
- Поскольку вы развертываете проект локально, укажите, что вы хотите использовать локальный файл, а не Google Cloud Secret Manager.
- Запустите локальный эмулятор:
firebase emulators:start
Установка и тестирование с реальным проектом Firebase
Вы можете установить расширение в реальный проект Firebase. Рекомендуется использовать для тестирования тестовый проект. Используйте этот рабочий процесс, если хотите протестировать сквозной поток данных расширения или если триггер вашего расширения ещё не поддерживается набором эмуляторов Firebase (см. раздел «Эмулятор расширений »). В настоящее время эмуляторы поддерживают функции, запускаемые HTTP-запросами, и фоновые функции, запускаемые событиями, для Cloud Firestore, Realtime Database и Pub/Sub.
- Создайте новый каталог в вашей хост-системе и подключите этот каталог к вашему проекту Firebase с помощью
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Затем из этого каталога выполните команду
firebase ext:install
для установки расширения. Замените/path/to/extension
на абсолютный путь к каталогу, содержащему файлextension.yaml
. Это запустит процесс установки расширения и создаст файл.env
с вашими конфигурациями перед их отправкой в Firebase или на эмуляторы.
firebase ext:install /path/to/extension
- Поскольку вы хотите выполнить развертывание непосредственно в Firebase и использовать Google Cloud Secret Manager, перед установкой расширения вам необходимо активировать API Secret Manager .
- Разверните в своем проекте Firebase.
firebase deploy
Протестируйте расширение
- После запуска
firebase deploy
илиfirebase emulators:start
перейдите на вкладку Firestore либо в консоли Firebase , либо в веб-представлении эмуляторов, в зависимости от ситуации. - Добавить документ в коллекцию, указанную полями
x
иy
. В этом случае обновлённые документы находятся в каталогеu/{uid}
с полемx
=xv
и полемy
=yv
.
- Если установка расширения прошла успешно, после сохранения двух полей расширение создаст в документе новое поле с именем
hash
.
8. Поздравляем!
Вы успешно преобразовали свою первую облачную функцию в расширение Firebase!
Вы добавили файл extension.yaml
и настроили его, чтобы разработчики могли выбирать способ развертывания вашего расширения. Затем вы создали пользовательскую документацию, содержащую рекомендации разработчикам расширения о том, что им следует сделать перед его настройкой и какие действия им может потребоваться выполнить после успешной установки расширения.
Теперь вы знаете основные шаги, необходимые для преобразования функции Firebase в распространяемое расширение Firebase.