Avec Cloud Functions, vous pouvez gérer les événements dans Cloud Firestore sans avoir besoin de mettre à jour le code client. Vous pouvez apporter des modifications à Cloud Firestore via l'interface d'instantané de document 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.
- 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 d'écriture ou de mise à jour, 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, pensez à spécifier l' emplacement de la fonction, le cas échéant.
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.