Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Activadores de Cloud Firestore

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Con Cloud Functions, puede manejar eventos en Cloud Firestore sin necesidad de actualizar el código del cliente. Puede realizar cambios en Cloud Firestore a través de la interfaz de DocumentSnapshot o a través del SDK de administrador .

En un ciclo de vida típico, una función de Cloud Firestore hace lo siguiente:

  1. Espera cambios en un documento en particular.
  2. Se activa cuando ocurre un evento y realiza sus tareas (consulte ¿Qué puedo hacer con Cloud Functions? para obtener ejemplos de casos de uso).
  3. Recibe un objeto de datos que contiene una instantánea de los datos almacenados en el documento especificado. Para los eventos onWrite o onUpdate , el objeto de datos contiene dos instantáneas que representan el estado de los datos antes y después del evento desencadenante.

La distancia entre la ubicación de la instancia de Firestore y la ubicación de la función puede generar una latencia de red significativa. Para optimizar el rendimiento, considere especificar la ubicación de la función cuando corresponda.

Desencadenadores de funciones de Cloud Firestore

El SDK de Cloud Functions para Firebase exporta un objeto functions.firestore que le permite crear controladores vinculados a eventos específicos de Cloud Firestore.

Tipo de evento Generar
onCreate Se activa cuando se escribe en un documento por primera vez.
onUpdate Se activa cuando un documento ya existe y tiene algún valor cambiado.
onDelete Se activa cuando se elimina un documento con datos.
onWrite Se activa cuando se activa onCreate , onUpdate o onDelete .

Si aún no tiene un proyecto habilitado para Cloud Functions para Firebase, lea Primeros pasos: escriba e implemente sus primeras funciones para configurar su proyecto de Cloud Functions para Firebase.

Escritura de funciones activadas por Cloud Firestore

Definir un activador de función

Para definir un activador de Cloud Firestore, especifique una ruta de documento y un tipo de evento:

Nodo.js

const functions = require('firebase-functions');

exports.myFunction = functions.firestore
  .document('my-collection/{docId}')
  .onWrite((change, context) => { /* ... */ });

Las rutas de los documentos pueden hacer referencia a un documento específico oa un patrón comodín .

Especificar un solo documento

Si desea activar un evento para cualquier cambio en un documento específico, puede usar la siguiente función.

Nodo.js

// Listen for any change on document `marie` in collection `users`
exports.myFunctionName = functions.firestore
    .document('users/marie').onWrite((change, context) => {
      // ... Your code here
    });

Especificar un grupo de documentos usando comodines

Si desea adjuntar un activador a un grupo de documentos, como cualquier documento de una determinada colección, utilice un {wildcard} en lugar del ID del documento:

Nodo.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"}
    });

En este ejemplo, cuando se cambia cualquier campo en cualquier documento en users , coincide con un comodín llamado userId de usuario.

Si un documento en users tiene subcolecciones y se cambia un campo en uno de los documentos de esas subcolecciones, el comodín de userId de usuario no se activa.

Las coincidencias con comodines se extraen de la ruta del documento y se almacenan en context.params . Puede definir tantos comodines como desee para sustituir ID de documentos o colecciones explícitos, por ejemplo:

Nodo.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"}
    });

Activadores de eventos

Activar una función cuando se crea un nuevo documento

Puede activar una función para que se active cada vez que se crea un nuevo documento en una colección mediante el uso de un controlador onCreate() con un comodín . Esta función de ejemplo llama a createUser cada vez que se agrega un nuevo perfil de usuario:

Nodo.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 ...
    });

Activar una función cuando se actualiza un documento

También puede activar una función para que se active cuando se actualiza un documento utilizando la función onUpdate() con un comodín . Esta función de ejemplo llama a updateUser si un usuario cambia su perfil:

Nodo.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 ...
    });

Activar una función cuando se elimina un documento

También puede activar una función cuando se elimina un documento utilizando la función onDelete() con un comodín . Esta función de ejemplo llama a deleteUser cuando un usuario elimina su perfil de usuario:

Nodo.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 ...
    });

Activar una función para todos los cambios en un documento

Si no le importa el tipo de evento que se activa, puede escuchar todos los cambios en un documento de Cloud Firestore mediante la función onWrite() con un comodín . Esta función de ejemplo llama a modifyUser si se crea, actualiza o elimina un usuario:

Nodo.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 ...
    });

Lectura y escritura de datos

Cuando se activa una función, proporciona una instantánea de los datos relacionados con el evento. Puede usar esta instantánea para leer o escribir en el documento que desencadenó el evento, o usar el SDK de administración de Firebase para acceder a otras partes de su base de datos.

Datos de eventos

Lectura de datos

Cuando se activa una función, es posible que desee obtener datos de un documento que se actualizó u obtener los datos antes de la actualización. Puede obtener los datos anteriores utilizando change.before.data() , que contiene la instantánea del documento antes de la actualización. De manera similar, change.after.data() contiene el estado de la instantánea del documento después de la actualización.

Nodo.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();
    });

Puede acceder a las propiedades como lo haría en cualquier otro objeto. Alternativamente, puede usar la función get para acceder a campos específicos:

Nodo.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');

Escritura de datos

Cada invocación de función está asociada con un documento específico en su base de datos de Cloud Firestore. Puede acceder a ese documento como DocumentReference en la propiedad ref de la instantánea devuelta a su función.

Esta DocumentReference proviene del SDK de Node.js de Cloud Firestore e incluye métodos como update() , set() y remove() para que pueda modificar fácilmente el documento que activó la función.

Nodo.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});
    });

Datos fuera del evento desencadenante

Cloud Functions se ejecuta en un entorno confiable, lo que significa que están autorizados como una cuenta de servicio en su proyecto. Puedes realizar lecturas y escrituras con el SDK de administración de Firebase :

Nodo.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({ ... });
  });

Limitaciones

Tenga en cuenta las siguientes limitaciones para los activadores de Cloud Firestore para Cloud Functions:

  • No se garantiza el pedido. Los cambios rápidos pueden desencadenar invocaciones de funciones en un orden inesperado.
  • Los eventos se entregan al menos una vez, pero un solo evento puede dar lugar a múltiples invocaciones de funciones. Evite depender de la mecánica exactamente una vez y escriba funciones idempotentes .
  • Los activadores de Cloud Firestore para Cloud Functions solo están disponibles para Cloud Firestore en modo nativo . No está disponible para Cloud Firestore en modo Datastore.