En este instructivo, se demuestra cómo escribir una app para dispositivos móviles con almacenamiento de datos de backend, sincronización en tiempo real y registro de eventos de usuarios mediante Firebase. Los servlets de Java que se ejecutan en el entorno flexible de App Engine de Google Cloud Platform (GCP) escuchan registros de usuarios nuevos almacenados en Firebase y los procesan.
En las instrucciones, se muestra cómo hacerlo con Firebase y el entorno flexible de App Engine.
Si deseas que tu aplicación procese datos del usuario o que organice eventos, puedes extender Firebase con el entorno flexible de App Engine para realizar una sincronización automática de datos en tiempo real.
La app de muestra, Playchat, almacena mensajes de chat en Firebase Realtime Database, que sincroniza esos datos en todos los dispositivos de forma automática. Playchat también escribe los registros de eventos del usuario en Firebase. Si quieres obtener más información sobre cómo la base de datos sincroniza los datos, consulta ¿Cómo funciona? en la documentación de Firebase.
En el siguiente diagrama, se muestra la arquitectura del cliente de Playchat.
Un conjunto de servlets de Java que se ejecutan en el entorno flexible de App Engine se registran como objetos de escucha con Firebase. Los servlets responden a los nuevos registros de eventos del usuario y procesan los datos de registro. Los servlets usan transacciones para garantizar que solo un servlet maneje cada registro de eventos del usuario.
En el siguiente diagrama, se muestra la arquitectura del servidor de Playchat.
La comunicación entre la app y el servlet ocurre en tres partes:
Cuando un usuario nuevo se conecta a Playchat, la app solicita un servlet de registro para ese usuario y agrega una entrada en
/inbox/
en Firebase Realtime Database.Uno de los servlets acepta la asignación y actualiza el valor de la entrada a su identificador de servlet. El servlet usa una transacción de Firebase para garantizar que sea el único servlet que pueda actualizar el valor. Una vez actualizado el valor, todos los demás servlets ignoran la solicitud.
Cuando el usuario accede, cierra sesión o cambia a un nuevo canal, Playchat registra la acción en
/inbox/[SERVLET_ID]/[USER_ID]/
; en este caso,[SERVLET_ID]
es el identificador de la instancia del servlet y[USER_ID]
es un valor de hash que representa al usuario.El servlet detecta las entradas nuevas en la bandeja de entrada y recopila los datos de registro.
En esta app de muestra, los servlets copian los datos de registro de forma local y los muestran en una página web. En una versión de producción de esta app, los servlets podrían procesar los datos de registro o copiarlos en Cloud Storage, Cloud Bigtable o BigQuery para su almacenamiento y análisis.
Objetivos
En este instructivo, se muestra cómo realizar las siguientes acciones:
Compilar una app para Android, Playchat, que almacena datos en Firebase Realtime Database
Ejecutar un servlet de Java en los entornos flexibles de App Engine que se conecte a Firebase y reciba notificaciones cuando los datos almacenados en Firebase cambien
Usar estos dos componentes para compilar un servicio de backend distribuido de transmisión a fin de recolectar y procesar datos de registro
Costos
Firebase tiene un nivel de uso gratuito. Si el uso de estos servicios es menor que los límites especificados en el plan gratuito de Firebase, no se aplican cargos por usar Firebase.
Las instancias dentro del entorno flexible de App Engine se cobran según el costo de las máquinas virtuales subyacentes de Google Compute Engine.
Antes de comenzar
Instala el siguiente software:
- Git
- Android Studio 4.0 o superior
- Un dispositivo o emulador que ejecute Android 8.1 (nivel de API de 27) o superior con las API de Google
- Apache Maven 3.6.x o superior
- Java 8 o superior
- Google Cloud CLI
Para instalar el componente Java de App Engine de la CLI de gcloud, ejecuta el siguiente comando desde la línea de comandos.
gcloud components install app-engine-java
Clona el código de muestra
Clona el código de la app cliente de frontend.
git clone https://github.com/GoogleCloudPlatform/firebase-android-client
Clona el código del servlet de backend.
git clone https://github.com/GoogleCloudPlatform/firebase-appengine-backend
Genera una huella digital SHA-1 para la app
Si quieres autenticar tu app cliente para el Acceso con Google, debes proporcionar una huella digital SHA-1 del certificado. En este instructivo, se usa un almacén de claves de depuración. Para obtener más información sobre cómo crear versiones de la huella digital del almacén de claves, consulta Autentica tu cliente.
Compila un SHA-1 de tu almacén de claves de depuración.
keytool -list -v \ -alias androiddebugkey -keystore ~/.android/debug.keystore
Crea un proyecto de Firebase
Crea una cuenta de Firebase o inicia sesión en una cuenta existente.
Haz clic en Agregar proyecto.
Si es la primera vez que usas la página, haz clic en Crear un proyecto.
En Nombre del proyecto, ingresa:
Playchat
.Sigue los pasos de configuración restantes y, luego, haz clic en Crear proyecto.
- No es necesario que habilites Google Analytics en este proyecto.
Después de que el asistente aprovisione tu proyecto, haz clic en Continuar.
En la página Project Overview, haz clic en Configuración
y, luego, en Configuración del proyecto.Haz clic en el ícono de Android, que te lleva a la página Add Firebase to your Android app.
En Android package name, ingresa:
com.google.cloud.solutions.flexenv
.En Debug signing certificate SHA-1, ingresa el valor SHA-1 que generaste en la sección anterior.
Haz clic en Registrar app.
Sigue los pasos en la sección Descargar archivos de configuración para agregar el archivo
google-services.json
a tu proyecto.Haz clic en Siguiente, en la sección Descargar archivo de configuración.
Toma nota de los cambios sugeridos para los archivos
build.gradle
del nivel del proyecto y de la app.Haz clic en Siguiente en la sección Agregar el SDK de Firebase.
Haz clic en Ir a la consola para completar la configuración.
Crea Realtime Database
En Firebase console, selecciona el proyecto.
En el menú de la izquierda de la consola, selecciona Realtime Database en el grupo Compilar.
Haz clic en Crear base de datos en la sección Realtime Database.
Selecciona una ubicación cercana.
En el cuadro de diálogo Reglas de seguridad, selecciona Comenzar en modo de prueba y, luego, haz clic en Habilitar.
En este paso, se muestran los datos que almacenaste en Firebase. En los pasos posteriores de este instructivo, puedes repasar esta página web para ver los datos que la app cliente y el servlet de backend agregaron y actualizaron.
En la pestaña Reglas de la base de datos, asegúrate de contar con las reglas de seguridad para lectura y escritura que especifican una fecha 30 días en el futuro con la unidad de tiempo definida en Tiempo de época de Unix. Por ejemplo, si creas la regla el 4 de agosto, esta debería vencer después del 4 de septiembre.
{ "rules": { ".read": "now < 1659639249000", //2022-08-04 ".write": "now < 1659639249000" //2022-08-04 } }
Toma nota de la URL de Firebase de tu proyecto, que tiene el formato
https://[FIREBASE_PROJECT_ID].firebaseio.com/
y aparece junto al ícono de un vínculo.
Habilita la autenticación de Google para el proyecto de Firebase
Hay una variedad de proveedores de acceso que puedes configurar para conectarte a tu proyecto de Firebase. En este instructivo, aprenderás a configurar la autenticación para que un usuario pueda acceder con una Cuenta de Google.
En el menú de la izquierda de Firebase console, haz clic en Autenticación en el grupo Desarrollar.
Haz clic en Configurar el método de acceso o en Comenzar si es la primera vez que visitas la página.
En la pestaña Método de acceso, selecciona Google, usa el botón de activación Habilitar, selecciona el correo electrónico de asistencia y haz clic en Guardar.
Agrega una cuenta de servicio al proyecto de Firebase
El servlet de backend no usa una Cuenta de Google para acceder. En su lugar, se conecta a Firebase con una cuenta de servicio. Sigue los siguientes pasos a fin de crear una cuenta de servicio que pueda conectarse a Firebase y para agregar las credenciales de la cuenta de servicio al código del servlet.
En el menú de la izquierda de Firebase console, al lado de la página principal del proyecto de Playchat, selecciona el ícono de Configuración y, luego, Configuración del proyecto.
Selecciona la pestaña Cuentas de servicio y, luego, haz clic en el vínculo Administrar permisos de cuenta de servicio.
Haz clic en Crear cuenta de servicio.
Establece la siguiente configuración:
- En Nombre de la cuenta de servicio, ingresa
playchat-servlet
y, luego, haz clic en Crear y continuar. En Selecciona una función, selecciona Proyecto > Propietario y, luego, haz clic en Continuar.
Haga clic en Listo.
- En Nombre de la cuenta de servicio, ingresa
Haz clic en la cuenta de servicio que acabas de crear, en la pestaña CLAVES, haz clic en Agregar clave y, luego, en Crear clave nueva.
Junto a Tipo de clave, haz clic en JSON y, luego, en Crear para descargar la clave.
Guarda el archivo de claves JSON que descargaste para la cuenta de servicio en el proyecto de servicio de backend,
firebase-appengine-backend
, en el directoriosrc/main/webapp/WEB-INF/
. El nombre del archivo tiene el siguiente formato:Playchat-[UNIQUE_ID].json
.Edita
src/main/webapp/WEB-INF/web.xml
y los parámetros de inicialización de la siguiente manera:Reemplaza
JSON_FILE_NAME
por el nombre del archivo de claves JSON que descargaste.Reemplaza
FIREBASE_URL
por la URL de Firebase que anotaste antes.<init-param> <param-name>credential</param-name> <param-value>/WEB-INF/JSON_FILE_NAME</param-value> </init-param> <init-param> <param-name>databaseUrl</param-name> <param-value>FIREBASE_URL</param-value> </init-param>
Habilita la facturación y las API para el proyecto de Cloud Platform
Si quieres que el servicio de backend se ejecute en Cloud Platform, debes habilitar la facturación y las API para el proyecto. El proyecto de Cloud Platform es el mismo proyecto que creaste en Crea un proyecto de Firebase y tiene el mismo identificador de proyecto.
En Cloud Platform Console, selecciona el proyecto Playchat.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Habilita las API de App Engine Admin API and Compute Engine API.
Compila y luego implementa el servicio de backend
El servicio de backend en este ejemplo usa una configuración de Docker para especificar su entorno de hosting. Debido a esta personalización, debes usar el entorno flexible de App Engine en lugar del entorno estándar de App Engine.
Para compilar el servlet de backend y luego implementarlo en el entorno flexible de App Engine, puedes usar el complemento de Maven de Google App Engine. Este complemento ya está especificado en el archivo de compilación de Maven incluido en este ejemplo.
Configura el proyecto
Si quieres que Maven sea capaz de compilar el servlet de backend de manera adecuada, debes proporcionarle el proyecto de Google Cloud Platform (GCP) para que pueda iniciar los recursos del servlet en él. El identificador del proyecto de GCP y el identificador del proyecto de Firebase son los mismos.
Proporciona las credenciales que usa la CLI de gcloud para acceder a GCP.
gcloud auth login
Configura el proyecto como tu proyecto de Firebase con el siguiente comando y reemplaza [FIREBASE_PROJECT_ID] por el nombre del ID del proyecto de Firebase que anotaste antes.
gcloud config set project [FIREBASE_PROJECT_ID]
Verifica que el proyecto se haya configurado con una lista de las opciones de configuración.
gcloud config list
Si es la primera vez que usas App Engine, inicializa la app de App Engine:
gcloud app create
Ejecuta el servicio en el servidor local (opcional)
Cuando desarrolles un nuevo servicio de backend, ejecuta el servicio de forma local antes de implementarlo en App Engine para iterar con rapidez los cambios sin la sobrecarga que puede generar una implementación completa en App Engine.
Si ejecutas el servidor de forma local, este no usa una configuración de Docker ni se ejecuta en un entorno de App Engine. En su lugar, Maven garantiza que todas las bibliotecas dependientes estén instaladas de forma local y que la app se ejecute en el servidor web de Jetty.
En el directorio
firebase-appengine-backend
, crea y ejecuta el módulo de backend de manera local con el siguiente comando:mvn clean package appengine:run
Si instalaste Google Cloud CLI en un directorio que no sea
~/google-cloud-sdk
, agrega la ruta de instalación al comando como se muestra a continuación y reemplaza[PATH_TO_TOOL]
por tu ruta personalizada.mvn clean package appengine:run -Dgcloud.gcloud_directory=[PATH_TO_TOOL]
Si se te pregunta ¿Deseas que la aplicación “Python.app” acepte conexiones de red entrantes?, selecciona Permitir.
Cuando finalice la implementación, abre http://localhost:8080/printLogs para verificar que tu servicio de backend esté en ejecución. En la página web, se muestra Bandeja de entrada: seguido de un identificador de 16 dígitos. Este es el identificador de la bandeja de entrada del servlet que se ejecuta en tu máquina local.
Este identificador no cambia aunque actualices la página; tu servidor local pone en marcha una sola instancia del servlet. Esto es útil para realizar pruebas, porque solo hay un identificador de servlet almacenado en Firebase Realtime Database.
Para cerrar el servidor local, oprime Ctrl+C.
Implementa el servicio en el entorno flexible de App Engine
Cuando ejecutas el servicio de backend en el entorno flexible de App Engine, App Engine usa la configuración en /firebase-appengine-backend/src/main/webapp/Dockerfiles
para compilar el entorno de hosting en el que se ejecuta el servicio. El entorno flexible pone en marcha varias instancias del servlet y las escala verticalmente para satisfacer la demanda.
En el directorio
firebase-appengine-backend
, crea y ejecuta el módulo de backend de manera local con el siguiente comando:mvn clean package appengine:deploy
mvn clean package appengine:deploy -Dgcloud.gcloud_directory=[PATH_TO_GCLOUD]
A medida que se ejecuta la compilación, verás las líneas “Enviando contexto de compilación al daemon de Docker…”. El comando anterior sube tu configuración de Docker y la configura en el entorno flexible de App Engine.
Cuando finaliza la implementación, abre https://[FIREBASE_PROJECT_ID].appspot.com/printLogs
; en este caso, [FIREBASE_PROJECT_ID]
es el identificador de Crea un proyecto de Firebase. La página web muestra Bandeja de entrada: seguido de un identificador de 16 dígitos. Este es el identificador de la bandeja de entrada para un servlet que se ejecuta en el entorno flexible de App Engine.
Cuando actualizas la página, este identificador cambia de manera periódica a medida que App Engine pone en marcha múltiples instancias del servlet a fin de manejar las solicitudes entrantes de los clientes.
Agrega Firebase y Servicios de Google Play a la app para Android
La app cliente usa Firebase Realtime Database a fin de almacenar y sincronizar mensajes, además de documentar los registros de eventos del usuario. La app cliente usa Servicios de Google Play para autenticar a los usuarios con sus Cuentas de Google.
En Android Studio, selecciona Herramientas > SDK Manager.
Selecciona la pestaña SDK Tools.
Selecciona Google Play services si no se encuentra seleccionado.
Haz clic en Aceptar para instalarlo.
Selecciona Archivo > Abrir… y selecciona el directorio
firebase-android-client
.Espera a que la información del proyecto de Gradle se termine de compilar. Si se te solicita que uses el wrapper de Gradle, haz clic en Aceptar.
Los cambios en los archivos
build.gradle
de nivel de app y del proyecto que anotaste en Crea un proyecto de Firebase ya se realizaron en el código de muestra.
Ejecuta y prueba la app para Android
En Android Studio, con el proyecto
firebase-android-client
abierto, selecciona Ejecutar > Ejecutar “app”.Selecciona un dispositivo o emulador que ejecute Android 6.0 con las API de Google como tu dispositivo de prueba.
Cuando la app esté cargada en el dispositivo, accede con tu Cuenta de Google.
Haz clic en el menú a la izquierda del título de PlayChat y selecciona el canal de libros.
Ingresa un mensaje.
Cuando lo hagas, la app de Playchat almacenará tu mensaje en Firebase Realtime Database. Firebase sincroniza los datos almacenados en la base de datos de todos los dispositivos. Los dispositivos que ejecuten Playchat mostrarán el nuevo mensaje cuando un usuario seleccione el canal libros.
Verifica los datos
Luego de usar la app de Playchat para generar algunos eventos del usuario con la app de Playchat, puedes verificar que los servlets estén registrados a la escucha y recolecten registros de eventos del usuario.
Abre Firebase Realtime Database de tu app; en este caso [FIREBASE_PROJECT_ID]
es el identificador de Crea un proyecto de Firebase.
https://console.firebase.google.com/project/[FIREBASE_PROJECT_ID]/database/data
En la parte inferior de Firebase Realtime Database, en la ubicación de datos /inbox/
, hay un grupo de nodos con el prefijo client-
seguidos por una clave generada de forma aleatoria que representa el acceso de la cuenta del usuario. A la última entrada en este ejemplo, client-1240563753
, le sigue un identificador de 16 dígitos del servlet que se encuentra a la escucha de los eventos de registro de ese usuario, en este ejemplo, 0035806813827987
.
Justo arriba, en la ubicación de datos /inbox/
, se encuentran los identificadores de servlet de todos los servlets asignados por el momento. En este ejemplo, solo un servlet recolecta registros. En /inbox/[SERVLET_IDENTIFIER]
están los registros de usuario que la app escribió en ese servlet.
Abre la página de App Engine de tu servicio de backend en https://[FIREBASE_PROJECT_ID].appspot.com/printLogs
; en este caso [FIREBASE_PROJECT_ID]
es el identificador de Crea un proyecto de Firebase. En la página, se muestra el identificador del servlet que registró los eventos del usuario que generaste. También puedes ver las entradas de registro de esos eventos en el identificador de la bandeja de entrada del servlet.
Explora el código
La app para Android de Playchat define una clase, FirebaseLogger
, que usa a fin de escribir los registros de eventos del usuario en Firebase Realtime Database.
Cuando un usuario nuevo accede, Playchat llama a la función requestLogger
a fin de agregar una entrada nueva a la ubicación /inbox/
en Firebase Realtime Database y establece un objeto de escucha para poder responder cuando un servlet actualiza el valor de esa entrada y acepta la asignación.
Cuando un servlet actualiza el valor, Playchat quita el objeto de escucha y escribe el registro “Acceso” en la bandeja de entrada del servlet.
En el lado del servicio de backend, cuando se inicia una instancia del servlet, la función init(ServletConfig config)
en MessageProcessorServlet.java
se conecta a Firebase Realtime Database y agrega un objeto de escucha en la ubicación de datos /inbox/
.
Cuando se agrega una nueva entrada a la ubicación de datos /inbox/
, el servlet actualiza el valor con su identificador, una señal a la app de Playchat de que el servlet acepta la asignación a fin de procesar registros para ese usuario. El servlet usa las transacciones de Firebase para garantizar que solo un servlet pueda actualizar el valor y aceptar la asignación.
Después de que un servlet acepta una asignación para procesar los registros de eventos del usuario, agrega un objeto de escucha que detecta cuando la app de Playchat escribe un nuevo archivo de registro en la bandeja de entrada del servlet. El servlet responde mediante la recuperación de los datos de registro nuevos de Firebase Realtime Database.
Limpia
Sigue estos pasos a fin de evitar que se apliquen cargos a tu cuenta de Google Cloud Platform para los recursos que se usaron en este instructivo:Borra el proyecto de Cloud Platform y Firebase
La forma más sencilla de detener los cargos de facturación es borrar el proyecto que creaste para este instructivo. Aunque creaste el proyecto en Firebase Console, también puedes borrarlo en Cloud Platform Console, ya que los proyectos de Cloud Platform y Firebase son los mismos.
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
Borra las versiones no predeterminadas de tu app de App Engine
Si no quieres borrar tu proyecto de Cloud Platform y Firebase, puedes reducir los costos si eliminas las versiones no predeterminadas de tu app de entorno flexible de App Engine.
- En la consola de Google Cloud, ve a la página Versiones de App Engine.
- Selecciona la casilla de verificación de la versión no predeterminada de la app que deseas borrar.
- Para borrar la versión de la app, haz clic en Borrar.
¿Qué sigue?
Analiza y archiva datos: en este ejemplo, los servlets almacenan datos de registro solo en la memoria. Para ampliar esta muestra, puedes hacer que los servlets archiven, transformen y analicen los datos con servicios como Google Cloud Storage, Cloud Bigtable, Cloud Dataflow y BigQuery.
Distribuye de manera uniforme la carga de trabajo entre los servlets: App Engine proporciona ajuste de escala automático y manual. Con el ajuste de escala automático, el entorno flexible detecta cambios en la carga de trabajo y luego agrega o quita instancias de VM en el clúster. Con el manual, debes especificar un número estático de instancias para manejar el tráfico. Para obtener más información sobre cómo configurar el escalamiento, consulta la sección sobre configuración de escalamiento de servicio en la documentación de App Engine.
Debido a que los registros de actividad de los usuarios se asignan a los servlets mediante el acceso a Firebase Realtime Database, puede que la carga de trabajo no se distribuya de manera uniforme. Por ejemplo, un servlet podría procesar más registros de eventos del usuario que otros servlets.
Puedes mejorar la eficiencia si implementas un administrador de cargas de trabajo que controle la carga de trabajo de manera independiente en cada VM. Este balanceo de la carga de trabajo podría basarse en métricas como las solicitudes de registro por segundo o la cantidad de clientes en simultáneo.
Recupera registros de eventos del usuario no procesados: en esta implementación de muestra, si una instancia del servlet falla, la app cliente asociada con esa instancia no deja de enviar eventos de registro a la bandeja de entrada del servlet en Firebase Realtime Database. En una versión de producción de esta app, el servicio de backend debe detectar esta situación para recuperar los registros de eventos del usuario no procesados.
Implementa funciones adicionales con productos de IA de Cloud: explora cómo proporcionar funciones basadas en AA con productos y servicios de IA de Cloud. Por ejemplo, puedes ampliar esta implementación de ejemplo a fin de proporcionar una función de traducción de voz mediante una combinación de API de Voz a texto, Traducción y Texto a voz. Si quieres obtener más información, consulta Agrega traducción de voz a tu app para Android.