1. Avant de commencer
Une extension Firebase effectue une tâche ou un ensemble de tâches spécifiques en réponse à des requêtes HTTP ou à des événements déclencheurs provenant d'autres produits Firebase et Google, tels que Firebase Cloud Messaging, Cloud Firestore ou Pub/Sub.
Objectifs de l'atelier
Dans cet atelier de programmation, vous allez créer une extension Firebase pour le géohashage. Une fois déployée, votre extension convertit les coordonnées X et Y en géohashs en réponse aux événements Firestore ou par le biais d'invocations de fonctions appelables. Vous pouvez l'utiliser comme alternative à l'implémentation de la bibliothèque Geofire sur toutes vos plates-formes cibles pour stocker des données, ce qui vous fait gagner du temps.
Points abordés
- Comment transformer du code Cloud Functions existant en extension Firebase distribuable
- Configurer un fichier
extension.yaml
- Stocker des chaînes sensibles (clés API) dans une extension
- Autoriser les développeurs de l'extension à la configurer en fonction de leurs besoins
- Tester et déployer l'extension
Prérequis
- CLI Firebase (installer et se connecter)
- Un compte Google, comme un compte Gmail
- Node.js et
npm
- Votre environnement de développement préféré
2. Configuration
Obtenir le code
Tout ce dont vous avez besoin pour cette extension se trouve dans un dépôt GitHub. Pour commencer, récupérez le code et ouvrez-le dans l'environnement de développement de votre choix.
- Décompressez le fichier ZIP téléchargé.
- Pour installer les dépendances requises, ouvrez le terminal dans le répertoire
functions
et exécutez la commandenpm install
.
Configurer Firebase
Cet atelier de programmation vous encourage vivement à utiliser les émulateurs Firebase. Si vous souhaitez tester le développement d'extensions avec un véritable projet Firebase, consultez Créer un projet Firebase. Cet atelier de programmation utilise Cloud Functions. Par conséquent, si vous utilisez un véritable projet Firebase au lieu des émulateurs, vous devez passer à la formule Blaze.
Vous voulez passer à la suite ?
Vous pouvez télécharger une version complète de l'atelier de programmation. Si vous rencontrez des difficultés ou si vous souhaitez voir à quoi ressemble une extension terminée, consultez la branche codelab-end
du dépôt GitHub ou téléchargez le fichier ZIP terminé.
3. Examiner le code
- Ouvrez le fichier
index.ts
à partir du fichier ZIP. Notez qu'il contient deux déclarations Cloud Functions.
À quoi servent ces fonctions ?
Ces fonctions de démonstration sont utilisées pour le géohachage. Elles prennent une paire de coordonnées et la transforment en un format optimisé pour les requêtes géographiques dans Firestore. Les fonctions simulent l'utilisation d'un appel d'API afin que vous puissiez en savoir plus sur la gestion des types de données sensibles dans les extensions. Pour en savoir plus, consultez la documentation sur l'exécution de requêtes géographiques sur les données dans Firestore.
Constantes de fonction
Les constantes sont déclarées au début du fichier index.ts
. Certaines de ces constantes sont référencées dans les déclencheurs définis de l'extension.
index.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);
Déclencheur Firestore
La première fonction du fichier index.ts
se présente comme suit :
index.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,
}
);
});
Cette fonction est un déclencheur Firestore. Lorsqu'un événement d'écriture se produit dans la base de données, la fonction réagit à cet événement en recherchant un champ xv
et un champ yv
. Si ces deux champs existent, elle calcule le geohash et écrit le résultat dans un emplacement de sortie de document spécifié. Le document d'entrée est défini par la constante users/{uid}
, ce qui signifie que la fonction lit chaque document écrit dans la collection users/
, puis traite un geohash pour ces documents. Il génère ensuite le hachage dans un champ de hachage du même document.
Fonctions appelables
La fonction suivante du fichier index.ts
se présente comme suit :
index.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};
});
Notez la fonction onCall
. Cela indique que cette fonction est une fonction appelable, qui peut être appelée à partir du code de votre application cliente. Cette fonction appelable accepte les paramètres x
et y
et renvoie un geohash. Bien que cette fonction ne soit pas appelée directement dans cet atelier de programmation, elle est incluse ici à titre d'exemple de configuration dans l'extension Firebase.
4. Configurer un fichier extension.yaml
Maintenant que vous savez ce que fait le code Cloud Functions dans votre extension, vous êtes prêt à l'empaqueter pour la distribution. Chaque extension Firebase est fournie avec un fichier extension.yaml
qui décrit ce que fait l'extension et comment elle se comporte.
Un fichier extension.yaml
nécessite des métadonnées initiales sur votre extension. Chacune des étapes suivantes vous aide à comprendre la signification de tous les champs et pourquoi vous en avez besoin.
- Créez un fichier
extension.yaml
dans le répertoire racine du projet que vous avez téléchargé précédemment. Commencez par ajouter les éléments suivants :
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
Le nom de l'extension est utilisé comme base de l'ID d'instance de l'extension (les utilisateurs peuvent installer plusieurs instances d'une extension, chacune avec son propre ID). Firebase génère ensuite le nom des comptes de service et des ressources spécifiques à l'extension à l'aide de cet ID d'instance. Le numéro de version indique la version de votre extension. Il doit suivre le versionnage sémantique et vous devez le mettre à jour chaque fois que vous modifiez la fonctionnalité de l'extension. La version de la spécification de l'extension permet de déterminer quelle spécification des extensions Firebase suivre. Dans ce cas, v1beta
est utilisé.
- Ajoutez des informations conviviales au fichier YAML :
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
Le nom à afficher est une représentation conviviale du nom de votre extension lorsque les développeurs interagissent avec elle. La description donne un bref aperçu de ce que fait l'extension. Lorsque l'extension est déployée sur extensions.dev, elle ressemble à ceci :
- Spécifiez la licence du code dans votre extension.
...
license: Apache-2.0 # The license you want for the extension
- Indiquez qui a écrit l'extension et si la facturation est requise pour l'installer :
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
La section author
permet d'indiquer à vos utilisateurs qui contacter en cas de problème avec l'extension ou s'ils souhaitent en savoir plus à son sujet. billingRequired
est un paramètre obligatoire qui doit être défini sur true
, car toutes les extensions reposent sur Cloud Functions, qui nécessite la formule Blaze.
Cela couvre le nombre minimal de champs requis dans le fichier extension.yaml
pour identifier cette extension. Pour en savoir plus sur les autres informations d'identification que vous pouvez spécifier dans une extension, consultez la documentation.
5. Convertir le code Cloud Functions en ressource Extensions
Une ressource d'extension est un élément que Firebase crée dans le projet lors de l'installation d'une extension. L'extension devient alors propriétaire de ces ressources et dispose d'un compte de service spécifique qui les gère. Dans ce projet, ces ressources sont des fonctions Cloud, qui doivent être définies dans le fichier extension.yaml
, car l'extension ne créera pas automatiquement de ressources à partir du code du dossier des fonctions. Si vos fonctions Cloud Functions ne sont pas explicitement déclarées comme ressource, elles ne peuvent pas être déployées lorsque l'extension est déployée.
Emplacement de déploiement défini par l'utilisateur
- Permettez à l'utilisateur de spécifier l'emplacement où il souhaite déployer cette extension et de décider s'il est préférable d'héberger l'extension plus près de ses utilisateurs finaux ou de sa base de données. Dans le fichier
extension.yaml
, incluez l'option permettant de sélectionner un emplacement.
extension.yaml
Vous êtes maintenant prêt à écrire la configuration de la ressource de fonction.
- Dans le fichier
extension.yaml
, créez un objet de ressource pour la fonctionlocationUpdate
. Ajoutez ce qui suit au fichierextension.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}
Vous définissez name
comme nom de fonction défini dans le fichier index.ts
du projet. Vous spécifiez le type
de la fonction déployée, qui doit toujours être firebaseextensions.v1beta.function
pour le moment. Ensuite, vous définissez le properties
de cette fonction. La première propriété que vous définissez est le eventTrigger
associé à cette fonction. Pour refléter ce que l'extension prend actuellement en charge, vous utilisez le eventType
de providers/cloud.firestore/eventTypes/document.write
, qui se trouve dans la documentation Écrire des fonctions Cloud Functions pour votre extension. Vous définissez resource
comme emplacement des documents. Étant donné que votre objectif actuel est de refléter ce qui existe dans le code, le chemin d'accès au document écoute users/{uid}
, avec l'emplacement de la base de données par défaut qui le précède.
- L'extension a besoin d'autorisations en lecture et en écriture pour la base de données Firestore. À la toute fin du fichier
extension.yaml
, spécifiez les rôles IAM auxquels l'extension doit avoir accès pour pouvoir interagir avec la base de données dans le projet Firebase du développeur.
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
Le rôle datastore.user
provient de la liste des rôles IAM compatibles avec les extensions. Étant donné que l'extension va lire et écrire, le rôle datastore.user
est adapté ici.
- La fonction appelable doit également être ajoutée. Dans le fichier
extension.yaml
, créez une ressource sous la propriété "resources". Ces propriétés sont spécifiques à une fonction appelable :
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
Alors que la ressource précédente utilisait un eventTrigger
, vous utilisez ici un httpsTrigger
, qui couvre à la fois les fonctions appelables et les fonctions HTTPS.
Vérification du code
Vous avez dû effectuer de nombreuses configurations pour que votre fichier extension.yaml
corresponde à tout ce qui a été fait par le code dans votre fichier index.ts
. Voici à quoi devrait ressembler le fichier extension.yaml
complet à ce stade :
extension.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.
Vérification de l'état
À ce stade, vous avez configuré les éléments fonctionnels initiaux de l'extension. Vous pouvez donc l'essayer à l'aide des émulateurs Firebase.
- Si ce n'est pas déjà fait, appelez
npm run build
dans le dossier des fonctions du projet d'extensions téléchargé. - Créez un répertoire sur votre système hôte et associez-le à votre projet Firebase à l'aide de
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.
- À partir du même répertoire, exécutez
firebase ext:install
. Remplacez/path/to/extension
par le chemin d'accès absolu au répertoire contenant votre fichierextension.yaml
.
firebase ext:install /path/to/extension
This command does two things:
- Il vous invite à spécifier la configuration de l'instance d'extension et crée un fichier
*.env
contenant les informations de configuration de l'instance. - Il ajoute l'instance d'extension à la section
extensions
de votrefirebase.json
. Il sert de mappage entre l'ID d'instance et la version de l'extension. - Étant donné que vous déployez le projet localement, vous pouvez spécifier que vous souhaitez utiliser un fichier local plutôt que Google Cloud Secret Manager.
- Démarrez les émulateurs Firebase avec la nouvelle configuration :
firebase emulators:start
- Après avoir exécuté
emulators:start
, accédez à l'onglet "Firestore" dans la vue Web des émulateurs. - Ajoutez un document à la collection
users
avec un champ numériquexv
et un champ numériqueyv
.
- Si vous avez réussi à installer l'extension, elle crée un champ
hash
dans le document.
Effectuer un nettoyage pour éviter les conflits
- Une fois les tests terminés, désinstallez l'extension. Vous allez mettre à jour le code de l'extension et vous ne voulez pas entrer en conflit avec l'extension actuelle par la suite.
Les extensions permettent d'installer plusieurs versions de la même extension à la fois. En la désinstallant, vous vous assurez qu'il n'y a pas de conflit avec une extension précédemment installée.
firebase ext:uninstall geohash-ext
La solution actuelle fonctionne, mais comme mentionné au début du projet, une clé API est codée en dur pour simuler la communication avec un service. Comment utiliser la clé API de l'utilisateur final au lieu de celle fournie à l'origine ? Lisez la suite pour le savoir.
6. Rendre l'extension configurable par l'utilisateur
À ce stade de l'atelier de programmation, vous disposez d'une extension configurée pour être utilisée avec la configuration volontariste des fonctions que vous avez déjà écrites. Mais que se passe-t-il si votre utilisateur souhaite utiliser la latitude et la longitude au lieu de y et x pour les champs indiquant l'emplacement sur un plan cartésien ? Comment pouvez-vous également demander à l'utilisateur final de fournir sa propre clé API au lieu de lui permettre d'utiliser la clé API fournie ? Vous pourriez rapidement dépasser le quota de cette API. Dans ce cas, vous configurez et utilisez des paramètres.
Définir les paramètres de base dans le fichier extension.yaml
Commencez par convertir les éléments pour lesquels les développeurs peuvent potentiellement avoir une configuration personnalisée. Les premiers sont les paramètres XFIELD
et YFIELD
.
- Dans le fichier
extension.yaml
, ajoutez le code suivant, qui utilise les paramètres de champXFIELD
etYFIELD
. Ces paramètres se trouvent dans la propriété YAMLparams
définie précédemment :
extension.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 nomme le paramètre de manière visible pour vous, le producteur d'extensions. Vous utiliserez cette valeur ultérieurement lorsque vous spécifierez les valeurs des paramètres.
- label est un identifiant lisible par l'utilisateur qui indique au développeur le rôle du paramètre.
- description fournit une description détaillée de la valeur. Comme il est compatible avec Markdown, il peut renvoyer vers une documentation supplémentaire ou mettre en évidence des mots qui peuvent être importants pour le développeur.
- type définit le mécanisme de saisie permettant à un utilisateur de définir la valeur du paramètre. Il existe de nombreux types, y compris
string
,select
,multiSelect
,selectResource
etsecret
. Pour en savoir plus sur chacune de ces options, consultez la documentation. - validationRegex contraint l'entrée du développeur à une certaine valeur regex (dans l'exemple, elle est basée sur les consignes simples concernant les noms de champs disponibles ici). Si cela échoue…
- validationErrorMessage alerte le développeur sur la valeur d'échec.
- default correspond à la valeur si le développeur n'a saisi aucun texte.
- required signifie que le développeur n'est pas tenu de saisir du texte.
- immutable permet au développeur de mettre à jour cette extension et de modifier cette valeur. Dans ce cas, le développeur doit pouvoir modifier les noms de champs en fonction de l'évolution de ses besoins.
- example donne une idée de ce à quoi peut ressembler une entrée valide.
Il y avait beaucoup à comprendre !
- Il vous reste trois paramètres à ajouter au fichier
extension.yaml
avant d'ajouter un paramètre spécial.
- 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
Définir les paramètres sensibles
Vous devez maintenant gérer la clé API spécifiée par l'utilisateur. Il s'agit d'une chaîne sensible qui ne doit pas être stockée en texte brut dans la fonction. Stockez plutôt cette valeur dans Cloud Secret Manager. Il s'agit d'un emplacement spécial dans le cloud qui stocke les secrets chiffrés et les empêche d'être divulgués accidentellement. Le développeur doit payer pour utiliser ce service, mais cela ajoute une couche de sécurité supplémentaire à ses clés API et peut limiter les activités frauduleuses. La documentation utilisateur avertit le développeur qu'il s'agit d'un service payant, afin qu'il n'y ait pas de surprises au niveau de la facturation. Dans l'ensemble, l'utilisation est semblable à celle des autres ressources de chaîne mentionnées ci-dessus. La seule différence est le type appelé secret
.
- Dans votre fichier
extension.yaml
, ajoutez le code suivant :
extension.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
Mettez à jour les attributs resource
pour utiliser les paramètres.
Comme mentionné précédemment, la ressource (et non la fonction) définit la manière dont la ressource est observée. La ressource locationUpdate
doit donc être mise à jour pour utiliser le nouveau paramètre.
- Dans votre fichier
extension.yaml
, ajoutez le code suivant :
extension.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}
Vérifier le fichier extension.yaml
- Examinez le fichier
extension.yaml
. Voici un exemple :
extension.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.
Accéder aux paramètres dans le code
Maintenant que tous les paramètres sont configurés dans le fichier extension.yaml
, ajoutez-les au fichier index.ts
.
- Dans le fichier
index.ts
, remplacez les valeurs par défaut parprocess.env.PARAMETER_NAME
, qui récupère les valeurs de paramètre appropriées et les renseigne dans le code de la fonction déployée sur le projet Firebase du développeur.
index.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!;
Normalement, vous devez effectuer des vérifications de valeurs nulles avec les valeurs des variables d'environnement, mais dans ce cas, vous êtes sûr que les valeurs des paramètres sont correctement copiées. Le code est maintenant configuré pour fonctionner avec les paramètres de l'extension.
7. Créer une documentation utilisateur
Avant de tester le code sur des émulateurs ou sur la place de marché des extensions Firebase, l'extension doit être documentée pour que les développeurs sachent ce qu'ils obtiennent lorsqu'ils l'utilisent.
- Commencez par créer le fichier
PREINSTALL.md
, qui sert à décrire la fonctionnalité, les éventuels prérequis d'installation et les potentielles implications de facturation.
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)
- Pour gagner du temps lors de l'écriture de
README.md
pour ce projet, utilisez la méthode pratique :
firebase ext:info . --markdown > README.md
Il combine le contenu de votre fichier PREINSTALL.md
et des informations supplémentaires sur votre extension issues de votre fichier extension.yaml
.
Enfin, informez le développeur de l'extension de certains détails supplémentaires concernant l'extension qui vient d'être installée. Le développeur peut recevoir des instructions et des informations supplémentaires après l'installation, ainsi que des tâches post-installation détaillées, comme la configuration du code client.
- Créez un fichier
POSTINSTALL.md
, puis incluez les informations post-installation suivantes :
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);
});
Surveillance
Nous vous recommandons de surveiller l'activité de votre extension installée, y compris son état, son utilisation et ses journaux.
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
Cela recompile les fonctions afin que le dernier code source soit prêt à être déployé avec l'extension lorsqu'elle est déployée sur un émulateur ou directement sur Firebase.
Ensuite, créez un répertoire pour tester l'extension. Étant donné que l'extension a été développée à partir de fonctions existantes, ne la testez pas à partir du dossier dans lequel elle a été configurée, car cela tente également de déployer les fonctions et les règles Firebase en même temps.
Installer et tester avec les émulateurs Firebase
- Créez un répertoire sur votre système hôte et associez-le à votre projet Firebase à l'aide de
firebase init
.
mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Dans ce répertoire, exécutez
firebase ext:install
pour installer l'extension. Remplacez/path/to/extension
par le chemin d'accès absolu au répertoire contenant votre fichierextension.yaml
. Cela lance le processus d'installation de votre extension et crée un fichier.env
contenant vos configurations avant de les transférer vers Firebase ou les émulateurs.
firebase ext:install /path/to/extension
- Étant donné que vous déployez le projet en local, indiquez que vous souhaitez utiliser un fichier local plutôt que Google Cloud Secret Manager.
- Démarrez la suite d'émulateurs locale :
firebase emulators:start
Installer et tester avec un véritable projet Firebase
Vous pouvez installer votre extension dans un projet Firebase réel. Nous vous recommandons d'utiliser un projet de test pour vos tests. Utilisez ce workflow de test si vous souhaitez tester le flux de bout en bout de votre extension ou si le déclencheur de votre extension n'est pas encore compatible avec la suite d'émulateurs Firebase (consultez l'option d'émulateur d'extensions). Les émulateurs sont actuellement compatibles avec les fonctions déclenchées par des requêtes HTTP et les fonctions déclenchées par des événements en arrière-plan pour Cloud Firestore, Realtime Database et Pub/Sub.
- Créez un répertoire sur votre système hôte et associez-le à votre projet Firebase à l'aide de
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- Ensuite, à partir de ce répertoire, exécutez
firebase ext:install
pour installer l'extension. Remplacez/path/to/extension
par le chemin d'accès absolu au répertoire contenant votre fichierextension.yaml
. Cela lance le processus d'installation de votre extension et crée un fichier.env
contenant vos configurations avant de les transférer vers Firebase ou les émulateurs.
firebase ext:install /path/to/extension
- Étant donné que vous souhaitez déployer directement sur Firebase et utiliser Google Cloud Secret Manager, vous devez activer l'API Secret Manager avant d'installer l'extension.
- Déployez-le dans votre projet Firebase.
firebase deploy
Tester l'extension
- Après avoir exécuté
firebase deploy
oufirebase emulators:start
, accédez à l'onglet Firestore de la console Firebase ou de la WebView des émulateurs, selon le cas. - Ajoutez un document à la collection spécifiée par les champs
x
ety
. Dans ce cas, les documents mis à jour se trouvent à l'emplacementu/{uid}
avec un champx
défini surxv
et un champy
défini suryv
.
- Si vous avez réussi à installer l'extension, elle crée un champ
hash
dans le document après l'enregistrement des deux champs.
8. Félicitations !
Vous avez réussi à convertir votre première fonction Cloud en extension Firebase.
Vous avez ajouté un fichier extension.yaml
et l'avez configuré pour que les développeurs puissent choisir comment déployer votre extension. Vous avez ensuite créé une documentation utilisateur qui explique aux développeurs de l'extension ce qu'ils doivent faire avant de la configurer et les étapes qu'ils devront peut-être suivre après l'avoir installée.
Vous connaissez désormais les principales étapes nécessaires pour convertir une fonction Firebase en extension Firebase distribuable.