1. Avant de commencer
Une extension Firebase effectue une tâche spécifique ou un ensemble de tâches en réponse à des requêtes HTTP ou au déclenchement d'événements provenant d'autres produits Firebase et Google tels que Firebase Cloud Messaging, Cloud Firestore ou Pub/Sub.
Ce que vous construirez
Dans cet atelier de programmation, vous allez créer une extension Firebase pour le géohashing . Une fois déployée, votre extension convertit ensuite les coordonnées X et Y en géohashes en réponse aux événements Firestore ou via des invocations de fonctions appelables. Cela peut être utilisé comme alternative à la mise en œuvre de la bibliothèque Geofire sur toutes vos plates-formes cibles pour stocker des données, ce qui vous fait gagner du temps.
Ce que vous apprendrez
- Comment prendre le code Cloud Functions existant et le transformer en une extension Firebase distribuable
- Comment configurer un fichier
extension.yaml
- Comment stocker des chaînes sensibles (clés API) dans une extension
- Comment permettre aux développeurs de l'extension de la configurer en fonction de leurs besoins
- Comment tester et déployer l'extension
Ce dont vous aurez besoin
- Firebase CLI (installation et connexion)
- Un compte Google, comme un compte Gmail
- Node.js et
npm
- Votre environnement de développement préféré
2. Préparez-vous
Obtenez 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 votre environnement de développement préféré.
- 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 encourage fortement l'utilisation d'émulateurs Firebase. Si vous souhaitez essayer le développement d'extensions avec un vrai 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 au plan tarifaire Blaze .
Voulez-vous aller de l'avant ?
Vous pouvez télécharger une version complète de l'atelier de programmation. Si vous êtes bloqué en cours de route ou si vous voulez voir à quoi ressemble une extension terminée, consultez la branche codelab-end
du référentiel GitHub ou téléchargez le zip terminé.
3. Vérifiez le code
- Ouvrez le fichier
index.ts
à partir du fichier zip. Notez qu'il contient deux déclarations Cloud Functions.
A quoi servent ces fonctions ?
Ces fonctions de démonstration sont utilisées pour le géohashing. Ils prennent une paire de coordonnées et les transforment dans un format optimisé pour les requêtes géographiques dans Firestore. Les fonctions simulent l'utilisation d'un appel API afin que vous puissiez en savoir plus sur la gestion des types de données sensibles dans les extensions. Pour plus d'informations, 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 dès le début, 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
ressemble à ceci :
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
et, si ces deux champs existent, elle calcule le géohash et écrit la sortie 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 envoie ensuite le hachage dans un champ de hachage dans le même document.
Fonctions appelables
La fonction suivante dans le fichier index.ts
ressemble à ceci :
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 depuis le code de votre application client. Cette fonction appelable prend 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 élément à configurer dans l'extension Firebase.
4. Configurez un fichier extension.yaml
Maintenant que vous savez ce que fait le code Cloud Functions de votre extension, vous êtes prêt à le conditionner pour la distribution. Chaque extension Firebase est livrée 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 ce qui suit :
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 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 suivre le versioning sémantique et vous devez le mettre à jour chaque fois que vous apportez des modifications aux fonctionnalités de l'extension. La version de la spécification d'extension est utilisée pour déterminer quelle spécification d'extension Firebase suivre. Dans ce cas, v1beta
est utilisée.
- Ajoutez quelques détails conviviaux au fichier YAML :
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
Le nom d'affichage est une représentation conviviale du nom de votre extension lorsque les développeurs interagissent avec votre extension. 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 pour le code dans votre extension.
...
license: Apache-2.0 # The license you want for the extension
- Indiquez qui a écrit l'extension et si une facturation est requise ou non pour l'installer :
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
La section author
est utilisée pour indiquer à vos utilisateurs à qui s'adresser s'ils rencontrent des problèmes avec l'extension ou souhaitent plus d'informations à ce 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 plan Blaze.
Cela couvre le nombre minimum de champs requis dans le fichier extension.yaml
pour identifier cette extension. Pour plus de détails sur les autres informations d'identification que vous pouvez spécifier dans une extension, consultez la documentation .
5. Convertissez le code Cloud Functions en une 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 est alors propriétaire de ces ressources et dispose d'un compte de service spécifique qui les exploite. Dans ce projet, ces ressources sont des Cloud Functions, qui doivent être définies dans le fichier extension.yaml
car l'extension ne créera pas automatiquement de ressources à partir du code dans le dossier des fonctions. Si vos fonctions Cloud ne sont pas explicitement déclarées en tant que 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 serait préférable d'héberger l'extension plus près de ses utilisateurs finaux ou plus près 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 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 fonction en cours de déploiement, qui doit toujours être firebaseextensions.v1beta.function
, pour l'instant. Ensuite, vous définissez les 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 Write Cloud Functions de votre extension . Vous définissez la resource
comme l'emplacement des documents. Puisque votre objectif actuel est de refléter ce qui existe dans le code, le chemin du document écoute users/{uid}
, précédé de l'emplacement par défaut de la base de données.
- L'extension nécessite des 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 afin de travailler 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 pris en charge pour les extensions . Étant donné que l'extension va lire et écrire, le rôle datastore.user
convient ici.
- La fonction appelable doit également être ajoutée. Dans le fichier
extension.yaml
, créez une nouvelle 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 des codes
Cela a demandé beaucoup de configuration pour que votre extension.yaml
corresponde à tout ce qui est fait par le code dans votre fichier index.ts
. Voici à quoi devrait ressembler le fichier extension.yaml
terminé à ce moment :
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 réellement l'essayer à l'aide des émulateurs Firebase !
- Si vous ne l'avez pas déjà fait, appelez
npm run build
dans le dossier fonctions du projet d'extensions téléchargé. - Créez un nouveau répertoire sur votre système hôte et connectez ce répertoire à votre projet Firebase à l'aide
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 absolu du répertoire qui contient 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
. Cela agit comme une carte de l’ID d’instance à la version de l’extension. - Puisque 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 dans la collection
users
avec un champ numéroxv
et un champ numéroyv
.
- Si vous avez réussi à installer l'extension, celle-ci crée un nouveau champ appelé
hash
dans le document.
Faire le ménage 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 souhaitez pas entrer en conflit avec l'extension actuelle ultérieurement.
Les extensions permettent d'installer plusieurs versions de la même extension à la fois, donc en désinstallant, vous vous assurez qu'il n'y a pas de conflits 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, il existe une clé API 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 initialement ? Continuez à lire pour le découvrir.
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 avisé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 le localisation sur un plan cartésien ? De plus, comment pouvez-vous amener l'utilisateur final à fournir sa propre clé API, plutôt que de le laisser consommer 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. Le premier serait 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
précédemment définie :
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 d'une manière qui est visible pour vous, le producteur de l'extension. Utilisez cette valeur ultérieurement lors de la spécification des valeurs des paramètres.
- label est un identifiant lisible par l'homme pour le développeur pour lui faire savoir ce que fait le paramètre.
- description donne une description détaillée de la valeur. Étant donné que cela prend en charge le markdown, il peut créer un lien vers une documentation supplémentaire ou mettre en évidence des mots qui pourraient ê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, notamment
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 directives simples de nom de champ trouvées ici ) ; et si cela échoue...
- validationErrorMessage alerte le développeur de la valeur d'échec.
- La valeur par défaut correspond à ce que serait la valeur si le développeur n'avait saisi aucun texte.
- requis signifie que le développeur n’est pas tenu de saisir de texte.
- immuable permet au développeur de mettre à jour cette extension et de modifier cette valeur. Dans ce cas, le développeur devrait pouvoir modifier les noms des champs à mesure que ses besoins changent.
- L'exemple donne une idée de ce à quoi peut ressembler une entrée valide.
C'était beaucoup à comprendre !
- Vous disposez de trois paramètres supplémentaires à 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
Maintenant, vous devez 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 les secrets cryptés et empêche leur fuite accidentelle. Cela oblige le développeur à payer pour l'utilisation de ce service, mais cela ajoute une couche de sécurité supplémentaire sur ses clés API et limite potentiellement les activités frauduleuses. La documentation utilisateur prévient le développeur qu'il s'agit d'un service payant, afin qu'il n'y ait pas de surprise au niveau de la facturation. Dans l’ensemble, l’utilisation est similaire aux autres ressources de chaînes mentionnées ci-dessus. La seule différence est le type appelé secret
.
- Dans le 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
Mettre à jour les attributs resource
pour utiliser des 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 afin d'utiliser le nouveau paramètre.
- Dans le 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érifiez le fichier extension.yaml
- Examinez le fichier
extension.yaml
. Ça devrait ressembler a quelque chose comme ca:
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ètres appropriées et les remplit 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 souhaitez effectuer des vérifications 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 d'extension.
7. Créer une documentation utilisateur
Avant de tester le code sur des émulateurs ou sur le marché des extensions Firebase, l'extension doit être documentée afin que les développeurs sachent ce qu'ils obtiennent lorsqu'ils utilisent l'extension.
- Commencez par créer le fichier
PREINSTALL.md
, qui est utilisé pour décrire la fonctionnalité, les conditions préalables à l'installation et les implications potentielles en matière de facturation.
PRÉINSTALLER.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 du
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 détails supplémentaires sur votre extension à partir de votre fichier extension.yaml
.
Enfin, informez le développeur de l'extension de quelques détails supplémentaires concernant l'extension qui vient d'être installée. Le développeur peut obtenir des instructions et des informations supplémentaires après avoir terminé l'installation et peut effectuer des tâches post-installation détaillées, telles que la configuration du code client ici.
- Créez un fichier
POSTINSTALL.md
, puis incluez les informations de 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
À titre de bonne pratique, vous pouvez surveiller l'activité de votre extension installée, notamment en vérifiant son état de santé, 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'il est déployé sur un émulateur ou directement sur Firebase.
Ensuite, créez un nouveau répertoire à partir duquel tester l’extension. Étant donné que l'extension a été développée à partir de fonctions existantes, ne testez pas à partir du dossier dans lequel l'extension a été configurée, car celui-ci tente également de déployer les fonctions et les règles Firebase à côté.
Installer et tester avec les émulateurs Firebase
- Créez un nouveau répertoire sur votre système hôte et connectez ce répertoire à votre projet Firebase à l'aide
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 qui contient votre fichierextension.yaml
. Cela démarre le processus d'installation de votre extension et crée un fichier.env
contenant vos configurations avant de transmettre la configuration à Firebase ou aux émulateurs.
firebase ext:install /path/to/extension
- Puisque vous déployez le projet localement, précisez que vous souhaitez utiliser un fichier local plutôt que Google Cloud Secret Manager.
- Démarrez la suite d'émulateurs locaux :
firebase emulators:start
Installer et tester avec un vrai projet Firebase
Vous pouvez installer votre extension dans un projet Firebase réel. Il est recommandé 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 pris en charge par la suite d'émulateurs Firebase (voir l' option d'émulateur Extensions ). Les émulateurs prennent actuellement en charge 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 nouveau répertoire sur votre système hôte et connectez ce répertoire à votre projet Firebase à l'aide
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 qui contient votre fichierextension.yaml
. Cela démarre le processus d'installation de votre extension et crée un fichier.env
contenant vos configurations avant de transmettre la configuration à Firebase ou aux émulateurs.
firebase ext:install /path/to/extension
- Puisque 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 sur votre projet Firebase.
firebase deploy
Testez l'extension
- Après avoir exécuté
firebase deploy
oufirebase emulators:start
, accédez à l'onglet Firestore de la console Firebase ou à la vue Web des émulateurs, selon le cas. - Ajoutez un document dans la collection spécifiée par le champ
x
et le champy
. Dans ce cas, les documents mis à jour sont situés àu/{uid}
avec un champx
dexv
et un champy
deyv
.
- Si vous avez réussi à installer l'extension, celle-ci crée un nouveau champ appelé
hash
dans le document après avoir enregistré les deux champs.
8. Félicitations !
Vous avez converti avec succès votre première fonction Cloud en une extension Firebase !
Vous avez ajouté un fichier extension.yaml
et l'avez configuré afin que les développeurs puissent sélectionner la manière dont ils souhaitent que votre extension soit déployée. Vous avez ensuite créé une documentation utilisateur qui fournit des conseils sur ce que les développeurs de l'extension doivent faire avant de configurer l'extension et sur les étapes qu'ils pourraient devoir suivre après avoir installé l'extension avec succès.
Vous connaissez maintenant les étapes clés nécessaires pour convertir une fonction Firebase en une extension Firebase distribuable.