Avec Cloud Functions, vous pouvez déployer du code pour gérer les événements déclenchés lorsque votre base de données Cloud Firestore compatible avec MongoDB est modifiée. Ce service vous permet d'ajouter des fonctionnalités côté serveur à votre application, sans avoir à gérer vos propres serveurs.
Cloud Functions (2e génération)
Optimisée par Cloud Run et Eventarc, Cloud Functions for Firebase (2e génération) vous offre une infrastructure plus puissante, un contrôle avancé des performances et de l'évolutivité, et un meilleur contrôle de l'environnement d'exécution des fonctions. Pour en savoir plus sur la 2e génération, consultez Cloud Functions pour Firebase (2e génération).
Déclencheurs de fonction Cloud Firestore compatible avec MongoDB
Le SDK Cloud Functions for Firebase exporte les déclencheurs d'événements Cloud Firestore compatible avec MongoDB suivants pour vous permettre de créer des gestionnaires associés à des événements Cloud Firestore compatible avec MongoDB spécifiques :
Node.js
| Type d'événement | Déclencheur |
|---|---|
onDocumentCreated |
Déclenché lorsqu'un document est écrit pour la première fois. |
onDocumentUpdated |
Déclenché lorsqu'un document existe déjà et qu'une valeur y a été modifiée. |
onDocumentDeleted |
Déclenché lorsqu'un document est supprimé. |
onDocumentWritten |
Déclenché lorsque onDocumentCreated, onDocumentUpdated ou onDocumentDeleted est déclenché. |
onDocumentCreatedWithAuthContext |
onDocumentCreated avec des informations d'authentification supplémentaires |
onDocumentWrittenWithAuthContext |
onDocumentWritten avec des informations d'authentification supplémentaires |
onDocumentDeletedWithAuthContext |
onDocumentDeleted avec des informations d'authentification supplémentaires |
onDocumentUpdatedWithAuthContext |
onDocumentUpdated avec des informations d'authentification supplémentaires |
Python
| Type d'événement | Déclencheur |
|---|---|
on_document_created |
Déclenché lorsqu'un document est écrit pour la première fois. |
on_document_updated |
Déclenché lorsqu'un document existe déjà et qu'une valeur y a été modifiée. |
on_document_deleted |
Déclenché lorsqu'un document est supprimé. |
on_document_written |
Déclenché lorsque on_document_created, on_document_updated ou on_document_deleted est déclenché. |
on_document_created_with_auth_context |
on_document_created avec des informations d'authentification supplémentaires |
on_document_updated_with_auth_context |
on_document_updated avec des informations d'authentification supplémentaires |
on_document_deleted_with_auth_context |
on_document_deleted avec des informations d'authentification supplémentaires |
on_document_written_with_auth_context |
on_document_written avec des informations d'authentification supplémentaires |
Les événements Cloud Firestore compatible avec MongoDB ne se déclenchent que lorsque le document est modifié. Une mise à jour d'un document Cloud Firestore compatible avec MongoDB où les données restent inchangées (écriture no-op) ne génère pas d'événement de mise à jour ou d'écriture. Il est impossible d'ajouter des événements à des champs spécifiques.
Si vous n'avez pas encore activé de projet pour Cloud Functions for Firebase, consultez la page Premiers pas avec Cloud Functions for Firebase (2e génération) pour en configurer un.Cloud Functions for Firebase
Écrire des fonctions déclenchées par Cloud Firestore compatible avec MongoDB
Définir un déclencheur de fonction
Pour définir un déclencheur Cloud Firestore compatible avec MongoDB, spécifiez un chemin de document et un type d'événement :
Node.js
const {
onDocumentWritten,
onDocumentCreated,
onDocumentUpdated,
onDocumentDeleted,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.myfunction = onDocumentWritten("my-collection/{docId}", (event) => {
/* ... */
});
Python
from firebase_functions.firestore_fn import (
on_document_created,
on_document_deleted,
on_document_updated,
on_document_written,
Event,
Change,
DocumentSnapshot,
)
@on_document_created(document="users/{userId}")
def myfunction(event: Event[DocumentSnapshot]) -> None:
Les chemins de document peuvent faire référence soit à un document spécifique, soit à un format contenant des caractères génériques.
Spécifier un document unique
Si vous souhaitez déclencher un événement chaque fois qu'une modification est constatée sur un document spécifique, vous pouvez utiliser la fonction suivante.
Node.js
const {
onDocumentWritten,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.myfunction = onDocumentWritten("users/marie", (event) => {
// Your code here
});
Python
from firebase_functions.firestore_fn import (
on_document_written,
Event,
Change,
DocumentSnapshot,
)
@on_document_written(document="users/marie")
def myfunction(event: Event[Change[DocumentSnapshot]]) -> None:
Spécifier un groupe de documents à l'aide de caractères génériques
Si vous souhaitez associer un déclencheur à un groupe de documents, tel que l'ensemble des documents d'une collection spécifique, utilisez un caractère générique {wildcard} à la place de l'identifiant du document :
Node.js
const {
onDocumentWritten,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.myfunction = onDocumentWritten("users/{userId}", (event) => {
// If we set `/users/marie` to {name: "Marie"} then
// event.params.userId == "marie"
// ... and ...
// event.data.after.data() == {name: "Marie"}
});
Python
from firebase_functions.firestore_fn import (
on_document_written,
Event,
Change,
DocumentSnapshot,
)
@on_document_written(document="users/{userId}")
def myfunction(event: Event[Change[DocumentSnapshot]]) -> None:
# If we set `/users/marie` to {name: "Marie"} then
event.params["userId"] == "marie" # True
# ... and ...
event.data.after.to_dict() == {"name": "Marie"} # True
Dans cet exemple, lorsqu'un champ de n'importe quel document de la collection users est modifié, il correspond au caractère générique userId.
Les correspondances de caractères génériques sont extraites du chemin du document et stockées dans le fichier event.params.
Votre déclencheur doit toujours pointer vers un document, même si vous utilisez un caractère générique.
Déclencheurs d'événements
Déclencher une fonction lorsqu'un document est créé
Vous pouvez déclencher une fonction chaque fois qu'un document est créé dans une collection. Cet exemple de fonction se déclenche chaque fois qu'un nouveau profil utilisateur est ajouté :
Node.js
const {
onDocumentCreated,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.createuser = onDocumentCreated("users/{userId}", (event) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const snapshot = event.data;
if (!snapshot) {
console.log("No data associated with the event");
return;
}
const data = snapshot.data();
// access a particular field as you would any JS property
const name = data.name;
// perform more operations ...
});
Pour obtenir des informations supplémentaires sur l'authentification, utilisez onDocumentCreatedWithAuthContext.
Python
from firebase_functions.firestore_fn import (
on_document_created,
Event,
DocumentSnapshot,
)
@on_document_created(document="users/{userId}")
def myfunction(event: Event[DocumentSnapshot]) -> None:
# Get a dictionary representing the document
# e.g. {'name': 'Marie', 'age': 66}
new_value = event.data.to_dict()
# Access a particular field as you would any dictionary
name = new_value["name"]
# Perform more operations ...
Déclencher une fonction lorsqu'un document est mis à jour
Vous pouvez également déclencher une fonction lorsqu'un document est mis à jour. Cet exemple de fonction se déclenche si un utilisateur modifie son profil :
Node.js
const {
onDocumentUpdated,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.updateuser = onDocumentUpdated("users/{userId}", (event) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const newValue = event.data.after.data();
// access a particular field as you would any JS property
const name = newValue.name;
// perform more operations ...
});
Pour obtenir des informations supplémentaires sur l'authentification, utilisez onDocumentUpdatedWithAuthContext.
Python
from firebase_functions.firestore_fn import (
on_document_updated,
Event,
Change,
DocumentSnapshot,
)
@on_document_updated(document="users/{userId}")
def myfunction(event: Event[Change[DocumentSnapshot]]) -> None:
# Get a dictionary representing the document
# e.g. {'name': 'Marie', 'age': 66}
new_value = event.data.after.to_dict()
# Access a particular field as you would any dictionary
name = new_value["name"]
# Perform more operations ...
Déclencher une fonction lorsqu'un document est supprimé
Vous pouvez également déclencher une fonction lorsqu'un document est supprimé. Cet exemple de fonction se déclenche lorsqu'un utilisateur supprime son profil utilisateur :
Node.js
const {
onDocumentDeleted,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.deleteuser = onDocumentDeleted("users/{userId}", (event) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const snap = event.data;
const data = snap.data();
// perform more operations ...
});
Pour obtenir des informations supplémentaires sur l'authentification, utilisez onDocumentDeletedWithAuthContext.
Python
from firebase_functions.firestore_fn import (
on_document_deleted,
Event,
DocumentSnapshot,
)
@on_document_deleted(document="users/{userId}")
def myfunction(event: Event[DocumentSnapshot|None]) -> None:
# Perform more operations ...
Déclencher une fonction pour toute modification apportée à un document
Si le type d'événement déclenché n'a pas d'importance pour vous, vous pouvez écouter toutes les modifications d'un document Cloud Firestore compatible avec MongoDB à l'aide du déclencheur d'événement "document écrit". Cet exemple de fonction se déclenche si un utilisateur est créé, mis à jour ou supprimé :
Node.js
const {
onDocumentWritten,
Change,
FirestoreEvent
} = require('firebase-functions/v2/firestore');
exports.modifyuser = onDocumentWritten("users/{userId}", (event) => {
// Get an object with the current document values.
// If the document does not exist, it was deleted
const document = event.data.after.data();
// Get an object with the previous document values
const previousValues = event.data.before.data();
// perform more operations ...
});
Pour obtenir des informations supplémentaires sur l'authentification, utilisez onDocumentWrittenWithAuthContext.
Python
from firebase_functions.firestore_fn import (
on_document_written,
Event,
Change,
DocumentSnapshot,
)
@on_document_written(document="users/{userId}")
def myfunction(event: Event[Change[DocumentSnapshot | None]]) -> None:
# Get an object with the current document values.
# If the document does not exist, it was deleted.
document = (event.data.after.to_dict()
if event.data.after is not None else None)
# Get an object with the previous document values.
# If the document does not exist, it was newly created.
previous_values = (event.data.before.to_dict()
if event.data.before is not None else None)
# Perform more operations ...
Lire et écrire des données
Lorsqu'une fonction est déclenchée, elle fournit un instantané des données associées à l'événement. Vous pouvez utiliser cet instantané pour lire ou écrire dans le document ayant 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
Lire les données
Lorsqu'une fonction est déclenchée, vous pouvez obtenir les données d'un document mis à jour ou récupérer la version antérieure à la mise à jour. Vous pouvez obtenir la version antérieure en utilisant event.data.before, qui contient l'instantané du document avant sa mise à jour.
De même, event.data.after contient l'état de l'instantané du document après sa mise à jour.
Node.js
exports.updateuser2 = onDocumentUpdated("users/{userId}", (event) => {
// Get an object with the current document values.
// If the document does not exist, it was deleted
const newValues = event.data.after.data();
// Get an object with the previous document values
const previousValues = event.data.before.data();
});
Python
@on_document_updated(document="users/{userId}")
def myfunction(event: Event[Change[DocumentSnapshot]]) -> None:
# Get an object with the current document values.
new_value = event.data.after.to_dict()
# Get an object with the previous document values.
prev_value = event.data.before.to_dict()
Vous pouvez accéder aux propriétés comme vous le feriez pour 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 = event.data.after.data().age;
const name = event.data.after.data()['name'];
// Fetch data using built in accessor
const experience = event.data.after.data.get('experience');
Python
# Get the value of a single document field.
age = event.data.after.get("age")
# Convert the document to a dictionary.
age = event.data.after.to_dict()["age"]
Écrire des données
Chaque appel de fonction est associé à un document spécifique de votre base de données Cloud Firestore compatible avec MongoDB. Vous pouvez accéder à ce document dans l'instantané renvoyé à votre fonction.
La référence du document inclut des méthodes telles que update(), set() et remove(), qui vous permettent de modifier le document ayant déclenché la fonction.
Node.js
const {onDocumentUpdated} = require('firebase-functions/v2/firestore');
exports.countnamechanges = onDocumentUpdated('users/{userId}', (event) => {
// Retrieve the current and previous value
const data = event.data.after.data();
const previousData = event.data.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 event.data.after.ref.set({
name_change_count: count + 1
}, {merge: true});
});
Python
@on_document_updated(document="users/{userId}")
def myfunction(event: Event[Change[DocumentSnapshot]]) -> None:
# Get the current and previous document values.
new_value = event.data.after
prev_value = event.data.before
# We'll only update if the name has changed.
# This is crucial to prevent infinite loops.
if new_value.get("name") == prev_value.get("name"):
return
# Retrieve the current count of name changes
count = new_value.to_dict().get("name_change_count", 0)
# Update the count
new_value.reference.update({"name_change_count": count + 1})
Accéder aux informations d'authentification des utilisateurs
Si vous utilisez l'un des types d'événements suivants, vous pouvez accéder aux informations d'authentification de l'utilisateur principal qui a déclenché l'événement. Ces informations s'ajoutent à celles renvoyées dans l'événement de base.
Node.js
onDocumentCreatedWithAuthContextonDocumentWrittenWithAuthContextonDocumentDeletedWithAuthContextonDocumentUpdatedWithAuthContext
Python
on_document_created_with_auth_contexton_document_updated_with_auth_contexton_document_deleted_with_auth_contexton_document_written_with_auth_context
Pour en savoir plus sur les données disponibles dans le contexte d'authentification, consultez Contexte d'authentification. L'exemple suivant montre comment récupérer des informations d'authentification :
Node.js
const {onDocumentWrittenWithAuthContext} = require('firebase-functions/v2/firestore');
exports.syncUser = onDocumentWrittenWithAuthContext("users/{userId}", (event) => {
const snapshot = event.data.after;
if (!snapshot) {
console.log("No data associated with the event");
return;
}
const data = snapshot.data();
// retrieve auth context from event
const { authType, authId } = event;
let verified = false;
if (authType === "system") {
// system-generated users are automatically verified
verified = true;
} else if (authType === "unknown" || authType === "unauthenticated") {
// admin users from a specific domain are verified
if (authId.endsWith("@example.com")) {
verified = true;
}
}
return data.after.ref.set({
created_by: authId,
verified,
}, {merge: true});
});
Python
@on_document_updated_with_auth_context(document="users/{userId}")
def myfunction(event: Event[Change[DocumentSnapshot]]) -> None:
# Get the current and previous document values.
new_value = event.data.after
prev_value = event.data.before
# Get the auth context from the event
user_auth_type = event.auth_type
user_auth_id = event.auth_id
Données situées à l'extérieur de l'événement déclencheur
Cloud Functions s'exécutent dans un environnement de confiance. Ils sont autorisés en tant que compte de service dans votre projet. Vous pouvez effectuer des opérations de lecture et d'écriture à l'aide du SDK Firebase Admin :
Node.js
const { initializeApp } = require('firebase-admin/app');
const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');
initializeApp();
const db = getFirestore();
exports.writetofirestore = onDocumentWritten("some/doc", (event) => {
db.doc('some/otherdoc').set({ ... });
});
exports.writetofirestore = onDocumentWritten('users/{userId}', (event) => {
db.doc('some/otherdoc').set({
// Update otherdoc
});
});
Python
from firebase_admin import firestore, initialize_app
import google.cloud.firestore
initialize_app()
@on_document_written(document="some/doc")
def myfunction(event: Event[Change[DocumentSnapshot | None]]) -> None:
firestore_client: google.cloud.firestore.Client = firestore.client()
firestore_client.document("another/doc").set({
# ...
})
Limites
- L'ordre n'est pas garanti. Les modifications rapides peuvent déclencher des appels de fonctions dans un ordre inattendu.
- Bien que les événements soient diffusés au moins une fois, un même événement peut produire plusieurs appels de fonction. Évitez de dépendre de procédés dits "exactement une fois" et écrivez des fonctions idempotentes.
- Un déclencheur est associé à une seule base de données. Vous ne pouvez pas créer de déclencheur qui correspond à 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 diffuser des événements, mais continue d'exister jusqu'à ce que vous le supprimiez.