Google Cloud Firestore
Cloud Firestore es uno de los tipos de base de datos NoSQL ofrecidos por Google Firebase para almacenar datos. Se trata de una base de datos NoSQL de tipo documental, en la que los datos se estructuran en colecciones, y que dichas colecciones contienen documentos (que son el conjunto de atributos y valores que definen un objeto). Cada colección tiene un nombre, mientras que cada documento tiene un identificador único.

Una característica interesante de Firestore para nuestro proyecto es que permite trabajar con datos en casi tiempo real, pudiendo gestionar miles de peticiones por segundo. Además permite actualizar datos de aplicaciones de forma automática cuando van llegando datos nuevos.
Cloud Functions es un framework sin servidores que permite ejecutar de forma automática el código de backend en respuesta a eventos como solicitudes https, mensajes de Pub/Sub, eventos en Google Storage, etc.
El código (se puede usar JavaScript o TypeScript, Python, Go, Java o .Net) se almacena en la nube de Google y se ejecuta en un entorno administrado. No es necesario provisionar ni escalar servidores ya que esto se hace de forma totalmente administrada.
El servicio se paga por uso (número de invocaciones, y consumo de memoria y ancho de banda, principalmente). El tramo gratuito permite hacer un número de llamadas más que suficiente para cubrir los objetivos de esta práctica.
Conectando Pub/Sub Con Cloud Firestore
Para esta tarea vamos a configurar una Cloud Function que se va a ejecutar cada vez que llegue un nuevo mensaje de PubSub con datos. Para ello, en la consola de Google Cloud vamos a Pub/Sub, seleccionamos el topic que queremos que haga las veces de disparador (En nuestro caso el topic al que se envían los datos del sensor), y pinchamos en el botón «Trigger cloud function«.

Nos llevará a la pantalla para crear y configurar una nueva Cloud Function. Debemos indicar un nombre para la función (elegir uno que sea identificativo de lo que hace la función). En región, indicar la región que estemos usando para nuestro proyecto. En nuestro ejemplo, «europe-west1». En el disparador (trigger) vamos a elegir qué es lo que va a provocar la ejecución de la función. Debemos seleccionar en este caso «Cloud Pub/Sub«, y en el desplegable de topic, elegir el topic al que estén llegando los datos del sensor de Co2 (debemos haberlo creado previamente. Ver guías anteriores). Pinchamos en «Save» y luego en «Next«.

En la siguiente pantalla debemos indicar el entorno de ejecución, el código de la función y las dependencias necesarias para que se ejecute. Podemos escribir la función en varios lenguajes (JavaScript, Python, Java, Go, .NET). En nuestro ejemplo vamos a escoger Python 3 (v3.7 o v3.8). Otro parámetro que hay que especificar es el «Entry point«, que es el nombre de la función dentro de nuestro código que se va a ejecutar. En este ejemplo la hemos llamado «telemetria_a_firestore«.

Editamos ahora el contenido del archivo «main.py» con el código de nuestra función. Observad que el nombre de la función que hemos definido coincide con el «entry point»:
import base64
import json
import logging
from google.cloud import firestore
db = firestore.Client()
def telemetria_a_firestore(event, context):
payload = base64.b64decode(event['data']).decode('utf-8')
telemetria = json.loads(payload)
atributos = event['attributes']
device_id = atributos['deviceId']
_, doc_ref = db.collection('dispositivos/{}/mediciones'.format(device_id)) .add({
'timestamp': telemetria['timestamp'],
'eco2': telemetria['eco2'],
'etvoc': telemetria['etvoc']
})
logging.info('Meensaje con ID: ' + doc_ref.id)
Ojo al copiar y pegar el código. Vigila los saltos de línea y las tabulaciones. El siguiente paso es indicar las dependencias en el archivo «requirements.txt». Editamos su contenido para que contenga las siguientes librerías:
google-cloud-logging
grpcio
google-cloud-firestore
google-cloud
El último paso sería pinchar en «deploy» para que la función se despliegue. Una vez que la función esté lista, cada vez que llegue un mensaje nuevo a pub/sub se ejecutará la función, pasando el contenido del evento de Pub/Sub en la variable «event«. Podemos probar si funciona usando la pestaña «Testing» dentro de los detalles de la función una vez que se ha creado.

Datos En Firestore
Si ponemos a funcionar el sistema de la guía anterior que envía datos desde el sensor de CO2 a Pub/Sub y tenemos desplegada nuestra función, si entramos en Cloud Firestore desde la consola de Google Cloud veremos como la base de datos se empieza a poblar con los valores del sensor.
