Avec Cloud Functions, vous pouvez gérer des événements dans Cloud Firestore sans avoir à mettre à jour le code client. Vous pouvez apporter des modifications à Cloud Firestore via l'interface DocumentSnapshot
ou via le SDK Admin .
Dans un cycle de vie typique, une fonction Cloud Firestore effectue les opérations suivantes :
- Attend les modifications apportées à un document particulier.
- Se déclenche lorsqu'un événement se produit et exécute ses tâches (voir Que puis-je faire avec Cloud Functions ? pour des exemples de cas d'utilisation).
- Reçoit un objet de données qui contient un instantané des données stockées dans le document spécifié. Pour les événements
onWrite
ouonUpdate
, l'objet de données contient deux instantanés qui représentent l'état des données avant et après l'événement déclencheur.
La distance entre l'emplacement de l'instance Firestore et l'emplacement de la fonction peut créer une latence réseau importante. Pour optimiser les performances, envisagez de spécifier l' emplacement de la fonction, le cas échéant.
Déclencheurs de fonction Cloud Firestore
Le SDK Cloud Functions for 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éclencheur |
---|---|
onCreate | Déclenché lorsqu'un document est écrit pour la première fois. |
onUpdate | Déclenché lorsqu'un document existe déjà et qu'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 :
Node.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 à un document spécifique ou à un modèle générique .
Spécifiez 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.
Node.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, comme n'importe quel document d'une certaine collection, utilisez un {wildcard}
à la place de l'ID de document :
Node.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 de n'importe quel 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 des ID de collection ou de document explicites, par exemple :
Node.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 lorsqu'un nouveau document est créé
Vous pouvez déclencher une fonction pour qu'elle se déclenche à chaque fois qu'un nouveau document est créé dans une collection en utilisant un gestionnaire onCreate()
avec un joker . Cet exemple de fonction appelle createUser
chaque fois qu'un nouveau profil utilisateur est ajouté :
Node.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 lorsqu'un document est mis à jour
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 joker . Cet exemple de fonction appelle updateUser
si un utilisateur modifie son profil :
Node.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é en utilisant la fonction onDelete()
avec un joker . Cet exemple de fonction appelle deleteUser
lorsqu'un utilisateur supprime son profil utilisateur :
Node.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é :
Node.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 de 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 précédentes 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.
Node.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. Vous pouvez également utiliser la fonction get
pour accéder à des champs spécifiques :
Node.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');
Écrire des données
Chaque invocation de fonction est associée à 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.
Node.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 de confiance, 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 :
Node.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 fonction dans un ordre inattendu.
- Les événements sont livrés au moins une fois, mais un seul événement peut entraîner plusieurs appels de fonction. Évitez de dépendre de la mécanique exactement une fois et écrivez des fonctions idempotentes .
- Les déclencheurs Cloud Firestore pour Cloud Functions sont disponibles uniquement pour Cloud Firestore en mode natif . Il n'est pas disponible pour Cloud Firestore en mode Datastore.