1. Avant de commencer
Une extension Firebase exécute 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éohachage. Une fois déployée, votre extension convertit les coordonnées X et Y en géocodes en réponse aux événements Firestore ou via des appels de fonction appelables. Vous pouvez utiliser cette méthode au lieu d'implémenter 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
- Convertir un code Cloud Functions existant en extension Firebase distribuable
- Configurer un fichier
extension.yaml
- Stocker des chaînes sensibles (clés API) dans une extension
- Permettre aux développeurs de l'extension de la configurer en fonction de leurs besoins
- Tester et déployer l'extension
Prérequis
- CLI Firebase (installation et connexion)
- 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 essayer de développer des extensions avec un véritable projet Firebase, consultez Créer un projet Firebase. Cet atelier de programmation utilise Cloud Functions. Si vous utilisez un véritable projet Firebase au lieu des émulateurs, vous devez passer à la formule Blaze.
Vous souhaitez passer à l'étape suivante ?
Vous pouvez télécharger une version finalisée 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 finalisé.
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éocodage. Ils prennent une paire de coordonnées et la convertissent dans 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 tôt, en haut 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 géohachage et écrit la sortie à 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 géohachage 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
. Il indique que cette fonction est une fonction appelable, qui peut être appelée à partir du code de votre application cliente. Cette fonction appelable utilise les paramètres x
et y
et renvoie un géocode. 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 de votre extension, vous pouvez le empaqueter pour le distribuer. Chaque extension Firebase est fournie avec un fichier extension.yaml
qui décrit son fonctionnement et son comportement.
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 sert de base à 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 de l'extension 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 respecter le gestion sémantique des versions, et vous devez le mettre à jour chaque fois que vous modifiez les fonctionnalités de l'extension. La version de la spécification de l'extension permet de déterminer la spécification d'extension 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 l'extension. Lorsque l'extension est déployée sur extensions.dev, elle se présente comme suit:
- 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 s'adresser s'ils rencontrent des problèmes avec l'extension ou souhaitent en savoir plus à son sujet. billingRequired
est un paramètre obligatoire et doit être défini sur true
, car toutes les extensions reposent sur Cloud Functions, qui nécessite le forfait Blaze.
Il s'agit du 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 créé par Firebase 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ée pas automatiquement de ressources à partir du code dans le dossier "functions". Si vos fonctions Cloud Functions ne sont pas explicitement déclarées comme une 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
- Autorisez l'utilisateur à spécifier l'emplacement où il souhaite déployer cette extension et à 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 choisir 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 le name
comme le nom de la fonction défini dans le fichier index.ts
du projet. Vous spécifiez le type
de la fonction qui est déployée, qui doit toujours être firebaseextensions.v1beta.function
pour le moment. Vous définissez ensuite 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 devez utiliser le eventType
de providers/cloud.firestore/eventTypes/document.write
, qui se trouve dans la documentation Écrire des fonctions Cloud 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 par défaut de la base de données qui le précède.
- L'extension a besoin d'autorisations de lecture et d'é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 utiliser 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é.
- 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: {}
Bien 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
Cela a nécessité beaucoup de configuration pour que votre extension.yaml
corresponde à tout ce qui est effectué par le code de votre fichier index.ts
. Le fichier extension.yaml
finalisé doit se présenter comme suit:
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 la tester à l'aide des émulateurs Firebase.
- Si vous ne l'avez pas déjà fait, appelez
npm run build
dans le dossier "functions" 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.
- Dans le même répertoire, exécutez
firebase ext:install
. Remplacez/path/to/extension
par le chemin absolu du répertoire contenant votre fichierextension.yaml
.
firebase ext:install /path/to/extension
This command does two things:
- Vous êtes invité à spécifier la configuration de l'instance de l'extension, et un fichier
*.env
contenant les informations de configuration de l'instance est créé. - Il ajoute l'instance d'extension à la section
extensions
de votrefirebase.json
. Il s'agit d'une mise en correspondance de l'ID d'instance avec la version de l'extension. - Comme vous déployez le projet localement, vous pouvez spécifier que vous souhaitez utiliser un fichier local plutôt que Secret Manager de Google Cloud.
- 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 de l'émulateur. - Ajoutez un document à la collection
users
avec un champ de numéroxv
et un champ de numéroyv
.
- Si vous avez réussi à installer l'extension, elle crée un champ nommé
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 qu'il entre en conflit avec l'extension actuelle plus tard.
Les extensions permettent d'installer plusieurs versions de la même extension à la fois. En les 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 indiqué au début du projet, une clé API codée en dur est utilisée pour simuler la communication avec un service. Comment utiliser la clé API de l'utilisateur final au lieu de celle fournie à l'origine ? Poursuivez votre lecture 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 orientée 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 ? De plus, comment pouvez-vous demander à l'utilisateur final de fournir sa propre clé API plutôt que de le laisser utiliser la clé API fournie ? Vous risqueriez rapidement de 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 avoir une configuration personnalisée. Le premier est 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 de l'extension. Utilisez cette valeur plus tard lorsque vous spécifiez les valeurs de paramètre.
- label est un identifiant lisible par l'utilisateur qui permet au développeur de savoir à quoi sert le paramètre.
- description fournit une description détaillée de la valeur. Étant donné que le format Markdown est pris en charge, il peut créer des liens vers des documents supplémentaires ou mettre en évidence des mots qui pourraient être importants pour le développeur.
- type définit le mécanisme d'entrée 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 limite la saisie du développeur à une certaine valeur d'expression régulière (dans l'exemple, elle est basée sur les consignes de dénomination de champ simple disponibles ici). Si cela échoue…
- validationErrorMessage avertit le développeur de la valeur d'échec.
- default correspond à la valeur qui serait utilisée si le développeur n'avait saisi aucun texte.
- obligatoire signifie que le développeur n'est pas obligé de saisir de 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 des champs à mesure que ses exigences évoluent.
- example donne une idée de ce à quoi peut ressembler une entrée valide.
C'était beaucoup à comprendre !
- Vous devez ajouter trois autres paramètres 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 des 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 le gestionnaire de secrets Cloud. Il s'agit d'un emplacement spécial dans le cloud qui stocke des secrets chiffrés et empêche leur fuite accidentelle. Le développeur doit donc payer pour utiliser ce service, mais il ajoute une couche de sécurité supplémentaire à ses clés API et limite potentiellement 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 surprise lors 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 réside dans le type, qui est 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
Modifier les attributs resource
pour utiliser des paramètres
Comme indiqué précédemment, la ressource (et non la fonction) définit la façon dont la ressource est observée. Par conséquent, la ressource locationUpdate
doit ê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 fonction déployé 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. Toutefois, dans ce cas, vous pouvez vous fier à la copie correcte des valeurs des paramètres. 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, vous devez documenter l'extension afin que les développeurs sachent ce qu'ils obtiennent lorsqu'ils l'utilisent.
- Commencez par créer le fichier
PREINSTALL.md
, qui permet de décrire la fonctionnalité, les conditions préalables à l'installation et les conséquences potentielles sur la 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 la rédaction de l'
README.md
pour ce projet, utilisez la méthode pratique:
firebase ext:info . --markdown > README.md
Cela combine le contenu de votre fichier PREINSTALL.md
et des informations supplémentaires sur votre extension à partir de votre fichier extension.yaml
.
Enfin, informez le développeur de l'extension de quelques informations supplémentaires sur l'extension qui vient d'être installée. Le développeur peut recevoir des instructions et des informations supplémentaires après avoir terminé l'installation. Il peut également recevoir des tâches détaillées post-installation, 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 en vérifiant 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
Les fonctions sont recompilées 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 à partir duquel vous pourrez 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
- À partir de ce répertoire, exécutez
firebase ext:install
pour installer l'extension. Remplacez/path/to/extension
par le chemin absolu du répertoire contenant votre fichierextension.yaml
. Le processus d'installation de votre extension démarre et un fichier.env
contenant vos configurations est créé avant d'être transféré 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 Secret Manager de Google Cloud.
- Démarrez la suite d'émulateurs locaux:
firebase emulators:start
Installer et tester avec un projet Firebase réel
Vous pouvez installer votre extension dans un projet Firebase réel. Nous vous recommandons d'utiliser un projet de test pour vos tests. Suivez 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 (voir l'option d'émulateur pour les 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 absolu du répertoire contenant votre fichierextension.yaml
. Le processus d'installation de votre extension démarre et un fichier.env
contenant vos configurations est créé avant d'être envoyé à Firebase ou aux é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 vue Web 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 dansu/{uid}
avec un champx
dexv
et un champy
deyv
.
- Si vous avez réussi à installer l'extension, elle crée un champ appelé
hash
dans le document une fois que vous avez enregistré les deux champs.
8. Félicitations !
Vous avez bien converti 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 indique ce que les développeurs de l'extension doivent faire avant de la configurer et les étapes qu'ils peuvent être amenés à suivre après avoir installé l'extension.
Vous savez maintenant quelles sont les étapes clés à suivre pour convertir une fonction Firebase en extension Firebase distribuable.