Con las funciones de Cloud Run y Eventarc, puedes desplegar código para gestionar eventos activados por cambios en tu base de datos de Firestore en el modo de Datastore. De esta forma, puedes añadir funciones del lado del servidor sin tener que ejecutar tus propios servidores.
Activadores del modo Datastore
Eventarc admite los siguientes activadores de eventos de Firestore en modo Datastore para que puedas crear controladores de funciones de Cloud Run (2.ª gen.) vinculados a eventos de Firestore en modo Datastore:
Tipo de evento | Activador |
---|---|
google.cloud.datastore.entity.v1.created |
Se activa cuando se escribe una entidad por primera vez. |
google.cloud.datastore.entity.v1.updated |
Se activa cuando una entidad ya existe y se ha modificado algún valor. |
google.cloud.datastore.entity.v1.deleted |
Se activa cuando se elimina una entidad. |
google.cloud.datastore.entity.v1.written |
Se activa cuando se activa created , updated o deleted . |
google.cloud.datastore.entity.v1.created.withAuthContext |
Es igual que created , pero añade información de autenticación. |
google.cloud.datastore.entity.v1.updated.withAuthContext |
Es igual que updated , pero añade información de autenticación. |
google.cloud.datastore.entity.v1.deleted.withAuthContext |
Es igual que deleted , pero añade información de autenticación. |
google.cloud.datastore.entity.v1.written.withAuthContext |
Es igual que written , pero añade información de autenticación. |
Los activadores de eventos del modo Datastore solo responden a los cambios de entidades. Si se actualiza una entidad del modo Datastore y los datos no cambian (una escritura sin operación), no se genera ningún evento de actualización ni de escritura. No puedes generar eventos solo para propiedades específicas.
Incluir el contexto de autenticación en el evento
Para incluir información de autenticación adicional sobre el evento, usa un activador de eventos con la extensión withAuthContext
. Esta extensión añade información adicional sobre la entidad de seguridad que ha activado el evento. Añade los atributos authtype
y authid
, además de la información devuelta en el evento base. Consulta la referencia de authcontext
para obtener más información sobre los valores de los atributos.
Escribir una función activada por entidades
Para escribir una función que responda a eventos de Firestore en modo Datastore, debes especificar lo siguiente durante la implementación:
- un tipo de evento de activación
- Un filtro de eventos de activador para seleccionar las entidades asociadas a la función
- El código de la función que se va a ejecutar
Filtros de eventos de activación
Cuando especifica un filtro de eventos, puede indicar una coincidencia exacta de una entidad o un patrón de ruta. Usa un patrón de ruta para buscar coincidencias con varias entidades mediante los comodines *
o **
.
Por ejemplo, puede especificar una concordancia exacta de entidad para responder a los cambios de la siguiente entidad:
users/marie
Usa comodines, *
o **
, para responder a los cambios en las entidades que coincidan con un patrón. El comodín *
coincide con un solo segmento, y el comodín **
coincide con cero o más segmentos del patrón.
En el caso de las coincidencias de un solo segmento (*
), también puedes usar un grupo de captura con nombre, como users/{userId}
.
En la siguiente tabla se muestran patrones de ruta válidos:
Patrón | Descripción |
---|---|
users/* o users/{userId} |
Coincide con todas las entidades del tipo users . No coincide con el nivel de las entidades secundarias, como /users/marie/messages/33e2IxYBD9enzS50SJ68 |
users/** |
Coincide con todas las entidades de tipo users y todas las entidades descendientes, como
/users/marie/messages/33e2IxYBD9enzS50SJ68 . |
Para obtener más información sobre los patrones de ruta, consulte Patrones de ruta de Eventarc.
El activador siempre debe apuntar a una entidad, aunque uses un comodín. Consulta los siguientes ejemplos:
users/{userId=*}/{messages=*}
no es válido porque{messages=*}
es un ID de tipo.users/{userId=*}/{messages}/{messageId=*}
es válido porque{messageId=*}
siempre apunta a una entidad.
Escape de caracteres
En esta sección se describen las situaciones en las que debe usar caracteres de escape en los IDs de tipo y los IDs de entidad. Si se escapa un carácter, el filtro de eventos podrá interpretar correctamente el ID.
Si un ID de tipo o un ID de entidad incluye un carácter
~
o/
, debe escapar el ID en el filtro de eventos. Para escapar un ID, usa el formato__escENCODED_ID__
. Sustituye ENCODED_ID por un ID de tipo o de entidad en el que se hayan sustituido todos los caracteres~
y/
por sus IDs de codificación, que son los siguientes:~
:~0
/
:~1
Por ejemplo, el ID de tipo
user/profile
se convierte en__escusers~1profile__
. Un ejemplo de patrón de ruta con este ID de tipo es__escusers~1profile__/{userId}
.Si usa el ID de tipo o el ID de entidad de
.
o..
en su filtro de eventos, debe escapar el ID de la siguiente manera:.
:__esc~2__
..
:__esc~2~2__
Solo tienes que usar el carácter de escape
.
si el ID es exactamente.
o..
. Por ejemplo, el ID de tipocustomers.info
no requiere formato de escape.Si el ID de tipo o de entidad es un valor numérico en lugar de un valor de cadena, debe usar
__idNUMERIC_VALUE__
para escapar el ID. Por ejemplo, el patrón de ruta de una entidad de tipo111
y con el ID de entidad222
es__id111__/__id222__
.Si has migrado de Legacy Cloud Datastore a Firestore en el modo de Datastore, es posible que tu base de datos contenga IDs antiguos con una codificación que no sea UTF-8. Debe usar el carácter de escape
__bytesBASE64_ENCODING__
para estos IDs. Sustituye BASE64_ENCODING por la codificación en base 64 del ID. Por ejemplo, el patrón de rutaTask/{task}
con escape para el ID de tipo no UTF-8Task
se convierte en__bytesVGFzaw==__/{task}
.
Funciones de ejemplo
En el siguiente ejemplo se muestra cómo recibir eventos del modo Datastore.
Para trabajar con los datos implicados en un evento, consulta los campos value
y old_value
.
value
: objetoEntityResult
que contiene una vista general de la entidad posterior a la operación. Este campo no se rellena en los eventos de eliminación.old_value
: objetoEntityResult
que contiene una entidad de preoperación. Este campo solo se rellena en los eventos de actualización y eliminación.
Java
Para saber cómo instalar y usar la biblioteca de cliente del modo Datastore, consulta Bibliotecas de cliente del modo Datastore. Para obtener más información, consulta la documentación de referencia de la API del modo Datastore Java.
Para autenticarte en el modo Datastore, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.
Incluye las dependencias de proto en tu fuente
Debe incluir el archivo Datastore mode data.proto
en el directorio de origen de su función. Este archivo importa los siguientes protos, que también debes incluir en tu directorio de origen:
Usa la misma estructura de directorios para las dependencias. Por ejemplo, coloca struct.proto
dentro de google/protobuf
.
Estos archivos son necesarios para decodificar los datos de eventos. Si la fuente de la función no incluye estos archivos, devuelve un error cuando se ejecuta.
Atributos de evento
Cada evento incluye atributos de datos que contienen información sobre el evento, como la hora en la que se ha activado. Firestore en modo Datastore añade datos adicionales sobre la base de datos y la entidad implicadas en el evento. Puedes acceder a estos atributos de la siguiente manera:
Java
logger.info("Event time " + event.getTime()); logger.info("Event project: " + event.getExtension("project")); logger.info("Event location: " + event.getExtension("location")); logger.info("Database name: " + event.getExtension("database")); logger.info("Database namespace: " + event.getExtension("namespace")); logger.info("Database entity: " + event.getExtension("entity")); // For withAuthContext events logger.info("Auth information: " + event.getExtension("authid")); logger.info("Auth information: " + event.getExtension("authtype"));
Desplegar una función
Los usuarios que implementen funciones de Cloud Run deben tener el rol de gestión de identidades y accesos Desarrollador de funciones de Cloud Run o un rol que incluya los mismos permisos. Consulta también la sección Configuración adicional para la implementación.
Puedes desplegar una función con la CLI de gcloud o con la consola Google Cloud . En el ejemplo que aparece más abajo se muestra una implementación con la CLI de gcloud. Para obtener información sobre la implementación con la Google Cloud consola, consulta Implementar funciones de Cloud Run.
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Usa el comando
gcloud functions deploy
para desplegar una función:gcloud functions deploy FUNCTION_NAME \ --gen2 \ --region=FUNCTION_LOCATION \ --trigger-location=TRIGGER_LOCATION \ --runtime=RUNTIME \ --source=SOURCE_LOCATION \ --entry-point=CODE_ENTRYPOINT \ --trigger-event-filters="type=EVENT_FILTER_TYPE" \ --trigger-event-filters="database=DATABASE" \ --trigger-event-filters="namespace=NAMESPACE" \ --trigger-event-filters-path-pattern="entity=ENTITY_OR_PATH" \
El primer argumento, FUNCTION_NAME, es el nombre de la función desplegada. El nombre de la función debe empezar por una letra, seguida de un máximo de 62 letras, números, guiones o guiones bajos, y debe terminar con una letra o un número. Sustituye FUNCTION_NAME por un nombre de función válido. A continuación, añade las siguientes marcas:
La marca
--gen2
especifica que quieres desplegar en Cloud Run Functions (2.ª gen.). Si se omite esta marca, la implementación se realizará en Cloud Run Functions (1.ª gen.).La marca
--region=FUNCTION_LOCATION
especifica la región en la que se desplegará la función.Para maximizar la proximidad, asigna a FUNCTION_LOCATION una región cercana a tu base de datos de Firestore. Si tu base de datos de Firestore está en una ubicación multirregional, asigna el valor
us-central1
a las bases de datos denam5
y el valoreurope-west4
a las bases de datos deeur3
. En el caso de las ubicaciones regionales de Firestore, debe ser la misma región.La marca
--trigger-location=TRIGGER_LOCATION
especifica la ubicación del activador. Debes definir TRIGGER_LOCATION en la ubicación de tu base de datos en el modo Datastore.La marca
--runtime=RUNTIME
especifica qué tiempo de ejecución de lenguaje usa tu función. Cloud Run Functions admite varios tiempos de ejecución. Consulta Tiempos de ejecución para obtener más información. Asigna a RUNTIME un tiempo de ejecución compatible.La marca
--source=SOURCE_LOCATION
especifica la ubicación del código fuente de tu función. Consulta la siguiente sección para obtener más información:- Implementar desde tu máquina local
- Implementar desde Cloud Storage
- Desplegar desde un repositorio de origen
Asigna a SOURCE_LOCATION la ubicación del código fuente de tu función.
La marca
--entry-point=CODE_ENTRYPOINT
especifica el punto de entrada de la función en el código fuente. Este es el código que ejecuta tu función cuando se pone en marcha. Debes asignar a CODE_ENTRYPOINT el nombre de una función o el nombre completo de una clase que exista en tu código fuente. Consulta Punto de entrada de la función para obtener más información.Las marcas
--trigger-event-filters
definen el filtro de eventos, que incluye el tipo de activador y la entidad o la ruta que activa los eventos. Asigne los siguientes valores de atributo para definir su filtro de eventos:type=EVENT_FILTER_TYPE
: Firestore admite los siguientes tipos de eventos:google.cloud.datastore.entity.v1.created
: el evento se envía cuando se escribe una entidad por primera vez.google.cloud.datastore.entity.v1.updated
: el evento se envía cuando ya existe una entidad y se ha cambiado algún valor.google.cloud.datastore.entity.v1.deleted
: el evento se envía cuando se elimina una entidad.google.cloud.datastore.entity.v1.written
: el evento se envía cuando se crea, actualiza o elimina una entidad.google.cloud.datastore.entity.v1.created.withAuthContext
: el evento se envía cuando se escribe en un documento por primera vez e incluye información de autenticación adicional.google.cloud.datastore.entity.v1.updated.withAuthContext
: el evento se envía cuando ya existe un documento y se ha cambiado algún valor. Incluye información de autenticación adicionalgoogle.cloud.datastore.entity.v1.deleted.withAuthContext
: event is sent when a document is deleted. Incluye información de autenticación adicional.google.cloud.datastore.entity.v1.written.withAuthContext
: el evento se envía cuando se crea, actualiza o elimina un documento y event. Incluye información de autenticación adicional
Asigna EVENT_FILTER_TYPE a uno de estos tipos de eventos.
database=DATABASE
: la base de datos de Firestore. En el nombre de la base de datos predeterminada, asigna el valor DATABASE a(default)
.namespace=NAMESPACE
: el espacio de nombres de la base de datos. En el nombre de la base de datos predeterminado, asigna el valor NAMESPACE a(default)
. Quita la marca para que coincida con cualquier espacio de nombres.entity=ENTITY_OR_PATH
: la ruta de la base de datos que activa eventos cuando se crean, actualizan o eliminan datos. Los valores aceptados para ENTITY_OR_PATH son:- Igual; por ejemplo,
--trigger-event-filters="entity='users/marie'"
- Patrón de ruta. Por ejemplo,
--trigger-event-filters-path-pattern="entity='users/*'"
. Para obtener más información, consulta Información sobre los patrones de ruta.
- Igual; por ejemplo,
Cuando despliegues una función, puedes especificar opciones adicionales de configuración, redes y seguridad.
Para obtener una referencia completa sobre el comando de implementación y sus marcas, consulta la documentación de
gcloud functions deploy
.
- Las funciones de Cloud Run (1.ª gen.) requieren una base de datos "(default)" en el modo nativo de Firestore. No admite bases de datos con nombre de Firestore ni el modo Datastore. En estos casos, utiliza funciones de Cloud Run (2.ª gen.) para configurar los eventos.
- No se garantiza la realización del pedido. Los cambios rápidos pueden activar invocaciones de funciones en un orden inesperado.
- Los eventos se entregan al menos una vez, pero un solo evento puede dar lugar a varias invocaciones de funciones. No dependas de los mecanismos de entrega exactamente una vez y escribe funciones idempotentes.
- Firestore en el modo de Datastore requiere funciones de Cloud Run (2.ª gen.). Cloud Run Functions (1.ª gen.) no admite el modo Datastore.
- Un activador está asociado a una sola base de datos. No puedes crear un activador que coincida con varias bases de datos.
- Si eliminas una base de datos, no se eliminarán automáticamente los activadores de esa base de datos. El activador deja de enviar eventos, pero sigue existiendo hasta que lo eliminas.
- Si un evento coincidente supera el tamaño máximo de solicitud, es posible que no se envíe a las funciones de Cloud Run (1.ª gen.).
- Los eventos que no se entregan debido al tamaño de la solicitud se registran en los registros de la plataforma y se tienen en cuenta en el uso de registros del proyecto.
- Puedes encontrar estos registros en el Explorador de registros con el mensaje "Event cannot deliver to
Cloud function due to size exceeding the limit for 1st gen..." (No se puede enviar el evento a la función de Cloud porque el tamaño supera el límite de la primera generación...) de
error
gravedad. Puedes encontrar el nombre de la función en el campofunctionName
. Si el camporeceiveTimestamp
sigue estando a menos de una hora, puedes inferir el contenido del evento leyendo el documento en cuestión con una instantánea antes y después de la marca de tiempo. - Para evitar este tipo de cadencia, puedes hacer lo siguiente:
- Migrar y actualizar a Cloud Run Functions (2.ª gen.)
- Reducir el tamaño del documento
- Elimina las funciones de Cloud Run en cuestión
- Puedes desactivar el registro mediante exclusiones, pero ten en cuenta que los eventos infractores seguirán sin enviarse.
- Consulta información sobre las arquitecturas basadas en eventos.
- Consulta los ejemplos de código del modo Datastore.
Ejemplos de implementaciones
En los siguientes ejemplos se muestran implementaciones con Google Cloud CLI.
Despliega una función para una base de datos en la región us-west2
:
gcloud functions deploy gcfv2-trigger-datastore-node \
--gen2 \
--region=us-west2 \
--trigger-location=us-west2 \
--runtime=nodejs18 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=makeUpperCase \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"
Implementa una función para una base de datos en la nam5
multirregión:
gcloud functions deploy gcfv2-trigger-datastore-python \
--gen2 \
--region=us-central1 \
--trigger-location=nam5 \
--runtime=python311 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=make_upper_case \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written.withAuthContext \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"
Limitaciones
Ten en cuenta las siguientes limitaciones de los activadores de Firestore para las funciones de Cloud Run:
Ubicaciones de Eventarc y Firestore en modo Datastore
Eventarc no admite multirregiones para los activadores de eventos de Firestore, pero puedes crear activadores para bases de datos de Firestore en ubicaciones multirregionales. Eventarc asigna las ubicaciones multirregión de Firestore a las siguientes regiones de Eventarc:
Multirregión de Firestore | Región de Eventarc |
---|---|
nam5 |
us-central1 |
eur3 |
europe-west4 |