Avec Cloud Functions, vous pouvez déployer du code Node.js pour gérer les événements déclenchés par les modifications apportées à votre base de données Cloud Firestore. Cela vous permet d'ajouter facilement des fonctionnalités côté serveur à votre application sans exécuter vos propres serveurs.
Pour obtenir des exemples de cas d'utilisation, consultez Que puis-je faire avec les fonctions Cloud ? ou le référentiel GitHub Functions Samples .
Déclencheurs de fonction Cloud Firestore
Le SDK Cloud Functions pour Firebase exporte un objet functions.firestore
qui vous permet de créer des gestionnaires liés à des événements Cloud Firestore spécifiques.
Type d'événement | Déclenchement |
---|---|
onCreate | Déclenché lorsqu'un document est écrit pour la première fois. |
onUpdate | Déclenché lorsqu'un document existe déjà et dont une valeur a été modifiée. |
onDelete | Déclenché lorsqu'un document contenant des données est supprimé. |
onWrite | Déclenché lorsque onCreate , onUpdate ou onDelete est déclenché. |
Si vous n'avez pas encore de projet activé pour Cloud Functions pour Firebase, lisez Premiers pas : écrivez et déployez vos premières fonctions pour configurer et configurer votre projet Cloud Functions pour Firebase.
Écrire des fonctions déclenchées par Cloud Firestore
Définir un déclencheur de fonction
Pour définir un déclencheur Cloud Firestore, spécifiez un chemin de document et un type d'événement :
Noeud.js
const functions = require('firebase-functions');
exports.myFunction = functions.firestore
.document('my-collection/{docId}')
.onWrite((change, context) => { /* ... */ });
Les chemins d'accès aux documents peuvent faire référence soit à un document spécifique , soit à un modèle générique .
Spécifier un seul document
Si vous souhaitez déclencher un événement pour toute modification apportée à un document spécifique, vous pouvez utiliser la fonction suivante.
Noeud.js
// Listen for any change on document `marie` in collection `users` exports.myFunctionName = functions.firestore .document('users/marie').onWrite((change, context) => { // ... Your code here });
Spécifier un groupe de documents à l'aide de caractères génériques
Si vous souhaitez attacher un déclencheur à un groupe de documents, tel que n'importe quel document d'une certaine collection, utilisez un {wildcard}
à la place de l'ID du document :
Noeud.js
// Listen for changes in all documents in the 'users' collection exports.useWildcard = functions.firestore .document('users/{userId}') .onWrite((change, context) => { // If we set `/users/marie` to {name: "Marie"} then // context.params.userId == "marie" // ... and ... // change.after.data() == {name: "Marie"} });
Dans cet exemple, lorsqu'un champ d'un document dans users
est modifié, il correspond à un caractère générique appelé userId
.
Si un document dans users
a des sous-collections et qu'un champ dans l'un des documents de ces sous-collections est modifié, le caractère générique userId
n'est pas déclenché.
Les correspondances génériques sont extraites du chemin du document et stockées dans context.params
. Vous pouvez définir autant de caractères génériques que vous le souhaitez pour remplacer les ID de collection ou de document explicites, par exemple :
Noeud.js
// Listen for changes in all documents in the 'users' collection and all subcollections exports.useMultipleWildcards = functions.firestore .document('users/{userId}/{messageCollectionId}/{messageId}') .onWrite((change, context) => { // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then // context.params.userId == "marie"; // context.params.messageCollectionId == "incoming_messages"; // context.params.messageId == "134"; // ... and ... // change.after.data() == {body: "Hello"} });
Déclencheurs d'événements
Déclencher une fonction lors de la création d'un nouveau document
Vous pouvez déclencher le déclenchement d'une fonction à chaque fois qu'un nouveau document est créé dans une collection en utilisant un gestionnaire onCreate()
avec un caractère générique . Cet exemple de fonction appelle createUser
chaque fois qu'un nouveau profil utilisateur est ajouté :
Noeud.js
exports.createUser = functions.firestore .document('users/{userId}') .onCreate((snap, context) => { // Get an object representing the document // e.g. {'name': 'Marie', 'age': 66} const newValue = snap.data(); // access a particular field as you would any JS property const name = newValue.name; // perform desired operations ... });
Déclencher une fonction lors de la mise à jour d'un document
Vous pouvez également déclencher le déclenchement d'une fonction lorsqu'un document est mis à jour à l'aide de la fonction onUpdate()
avec un caractère générique . Cet exemple de fonction appelle updateUser
si un utilisateur modifie son profil :
Noeud.js
exports.updateUser = functions.firestore .document('users/{userId}') .onUpdate((change, context) => { // Get an object representing the document // e.g. {'name': 'Marie', 'age': 66} const newValue = change.after.data(); // ...or the previous value before this update const previousValue = change.before.data(); // access a particular field as you would any JS property const name = newValue.name; // perform desired operations ... });
Déclencher une fonction lorsqu'un document est supprimé
Vous pouvez également déclencher une fonction lorsqu'un document est supprimé à l'aide de la fonction onDelete()
avec un caractère générique . Cet exemple de fonction appelle deleteUser
lorsqu'un utilisateur supprime son profil utilisateur :
Noeud.js
exports.deleteUser = functions.firestore .document('users/{userID}') .onDelete((snap, context) => { // Get an object representing the document prior to deletion // e.g. {'name': 'Marie', 'age': 66} const deletedValue = snap.data(); // perform desired operations ... });
Déclencher une fonction pour toutes les modifications apportées à un document
Si vous ne vous souciez pas du type d'événement déclenché, vous pouvez écouter toutes les modifications apportées à un document Cloud Firestore à l'aide de la fonction onWrite()
avec un caractère générique . Cet exemple de fonction appelle modifyUser
si un utilisateur est créé, mis à jour ou supprimé :
Noeud.js
exports.modifyUser = functions.firestore .document('users/{userID}') .onWrite((change, context) => { // Get an object with the current document value. // If the document does not exist, it has been deleted. const document = change.after.exists ? change.after.data() : null; // Get an object with the previous document value (for update or delete) const oldDocument = change.before.data(); // perform desired operations ... });
Lecture et écriture de données
Lorsqu'une fonction est déclenchée, elle fournit un instantané des données liées à l'événement. Vous pouvez utiliser cet instantané pour lire ou écrire dans le document qui a déclenché l'événement, ou utiliser le SDK Firebase Admin pour accéder à d'autres parties de votre base de données.
Données d'événement
Lecture des données
Lorsqu'une fonction est déclenchée, vous souhaiterez peut-être obtenir les données d'un document qui a été mis à jour ou obtenir les données avant la mise à jour. Vous pouvez obtenir les données antérieures en utilisant change.before.data()
, qui contient l'instantané du document avant la mise à jour. De même, change.after.data()
contient l'état de l'instantané du document après la mise à jour.
Noeud.js
exports.updateUser2 = functions.firestore .document('users/{userId}') .onUpdate((change, context) => { // Get an object representing the current document const newValue = change.after.data(); // ...or the previous value before this update const previousValue = change.before.data(); });
Vous pouvez accéder aux propriétés comme vous le feriez dans n’importe quel autre objet. Alternativement, vous pouvez utiliser la fonction get
pour accéder à des champs spécifiques :
Noeud.js
// Fetch data using standard accessors const age = snap.data().age; const name = snap.data()['name']; // Fetch data using built in accessor const experience = snap.get('experience');
Écriture de données
Chaque appel de fonction est associé à un document spécifique dans votre base de données Cloud Firestore. Vous pouvez accéder à ce document en tant que DocumentReference
dans la propriété ref
de l'instantané renvoyé à votre fonction.
Cette DocumentReference
provient du SDK Cloud Firestore Node.js et inclut des méthodes telles que update()
, set()
et remove()
afin que vous puissiez facilement modifier le document qui a déclenché la fonction.
Noeud.js
// Listen for updates to any `user` document. exports.countNameChanges = functions.firestore .document('users/{userId}') .onUpdate((change, context) => { // Retrieve the current and previous value const data = change.after.data(); const previousData = change.before.data(); // We'll only update if the name has changed. // This is crucial to prevent infinite loops. if (data.name == previousData.name) { return null; } // Retrieve the current count of name changes let count = data.name_change_count; if (!count) { count = 0; } // Then return a promise of a set operation to update the count return change.after.ref.set({ name_change_count: count + 1 }, {merge: true}); });
Données en dehors de l'événement déclencheur
Les fonctions Cloud s'exécutent dans un environnement fiable, ce qui signifie qu'elles sont autorisées en tant que compte de service sur votre projet. Vous pouvez effectuer des lectures et des écritures à l'aide du SDK Firebase Admin :
Noeud.js
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.writeToFirestore = functions.firestore
.document('some/doc')
.onWrite((change, context) => {
db.doc('some/otherdoc').set({ ... });
});
Limites
Notez les limitations suivantes pour les déclencheurs Cloud Firestore pour Cloud Functions :
- La commande n'est pas garantie. Des changements rapides peuvent déclencher des appels de fonctions dans un ordre inattendu.
- Les événements sont transmis au moins une fois, mais un seul événement peut entraîner plusieurs appels de fonctions. Évitez de dépendre de mécanismes exactement une fois et écrivez des fonctions idempotentes .
- Cloud Firestore en mode Datastore nécessite Cloud Functions (2e génération). Cloud Functions (1re génération) ne prend pas en charge le mode Datastore.
- Cloud Functions (1re génération) fonctionne uniquement avec la base de données « (par défaut) » et ne prend pas en charge les bases de données nommées Cloud Firestore. Veuillez utiliser Cloud Functions (2e génération) pour configurer des événements pour les bases de données nommées.
- Un déclencheur est associé à une seule base de données. Vous ne pouvez pas créer un déclencheur correspondant à plusieurs bases de données.
- La suppression d'une base de données ne supprime pas automatiquement les déclencheurs de cette base de données. Le déclencheur cesse de transmettre les événements mais continue d'exister jusqu'à ce que vous le supprimiez .
- Si un événement correspondant dépasse la taille maximale de la requête , l'événement risque de ne pas être transmis à Cloud Functions (1re génération).
- Les événements non livrés en raison de la taille de la demande sont enregistrés dans les journaux de la plateforme et sont pris en compte dans l'utilisation des journaux pour le projet.
- Vous pouvez trouver ces journaux dans l'explorateur de journaux avec le message « L'événement ne peut pas être transmis à la fonction Cloud en raison d'une taille dépassant la limite pour la 1ère génération... » de gravité de
error
. Vous pouvez trouver le nom de la fonction sous le champfunctionName
. Si le champreceiveTimestamp
est toujours dans une heure, vous pouvez déduire le contenu réel de l'événement en lisant le document en question avec un instantané avant et après l'horodatage. - Pour éviter une telle cadence, vous pouvez :
- Migrer et mettre à niveau vers Cloud Functions (2e génération)
- Réduire la taille du document
- Supprimer les Cloud Functions en question
- Vous pouvez désactiver la journalisation elle-même à l'aide d'exclusions , mais notez que les événements incriminés ne seront toujours pas transmis.