Crea una aplicación Android con Firebase y el entorno flexible de App Engine

En este tutorial se explica cómo generar una aplicación móvil con almacenamiento de datos de backend, sincronización en tiempo real y registro de eventos de usuario usando Firebase. Los servlets de Java que se ejecutan en el entorno flexible de Google App Engine escuchan los nuevos registros de usuarios almacenados en Firebase y los procesan.

En las instrucciones se explica cómo hacerlo mediante:

  • Firebase: una plataforma totalmente administrada para crear aplicaciones iOS, Android y web que proporciona sincronización automática de datos, servicios de autenticación, mensajería, almacenamiento de archivos, análisis y mucho más.

  • Entorno flexible de App Engine: una plataforma de aplicaciones que supervisa, actualiza y escala el entorno de alojamiento. El entorno flexible ejecuta tu servicio de backend dentro de contenedores Docker configurados con Dockerfiles. Esto significa que puedes llamar a archivos binarios nativos, escribir en el sistema de archivos y realizar otras llamadas al sistema.

Si tu aplicación necesita procesar datos de los usuarios u organizar eventos, ampliar Firebase con el entorno flexible de App Engine te brinda la ventaja de sincronizar automáticamente los datos en tiempo real, sin tener que ejecutar tu código dentro de la zona de pruebas del entorno estándar de App Engine.

La aplicación de muestra, Playchat, almacena los mensajes de chat en la Firebase Realtime Database, que sincroniza automáticamente esa información en todos los dispositivos. Playchat también escribe registros de eventos de usuario en Firebase.

Arquitectura del cliente Playchat

Un conjunto de servlets de Java ejecutados en el entorno flexible de App Engine se registran como oyentes con Firebase. Los servlets responden a los nuevos registros de eventos de usuario y procesan los datos de registro. Los servlets usan transacciones para garantizar que solo un servlet gestiona cada registro de evento de usuario.

Arquitectura del servidor Playchat

La comunicación entre la aplicación y el servlet se produce en tres partes:

  • Cuando un usuario nuevo inicia sesión en Playchat, la aplicación solicita un servlet de inicio de sesión para ese usuario al agregar una entrada en /requestLogger/ en la Firebase Realtime Database.

  • Uno de los servlets acepta la asignación actualizando el valor de la entrada a su identificador de servlet. El servlet usa una transacción de Firebase para garantizar que es el único servlet que puede actualizar el valor. Una vez que se actualiza el valor, todos los demás servlets ignoran la petición.

  • Cuando el usuario inicia sesión, cierra la sesión o cambia a un nuevo canal, Playchat registra la acción en /inbox/[SERVLET_ID]/[USER_ID]/, donde [SERVLET_ID] es el identificador de la instancia del servlet y [USER_ID] es un valor hash que representa al usuario.

  • El servlet vigila las nuevas entradas de la bandeja de entrada y recopila los datos de registro.

En esta aplicación de ejemplo, los servlets copian los datos de registro localmente y lo muestran en una página web. En una versión de producción de esta aplicación, los servlets podían procesar los datos de registro o copiarlos en Google Cloud Storage, Google Cloud Bigtable o Google BigQuery para su almacenamiento y análisis.

Objetivos

Este tutorial te enseña a:

  • Crear una aplicación de Android, Playchat, que almacena datos en la Firebase Realtime Database.

  • Ejecutar un servlet de Java en los entornos flexibles de App Engine que se conecta a Firebase y recibe notificaciones cuando cambian los datos almacenados en Firebase.

  • Utilizar estos dos componentes para crear un servicio de backend distribuido y de transmisión para recopilar y procesar datos de registro.

Costes

El nivel de uso de Firebase es gratuito. Si el uso que haces de estos servicios es inferior a los límites especificados en el plan gratuito de Firebase, no se aplicará ningún cargo por usar Firebase.

A las instancias dentro del entorno flexible de App Engine se les carga el coste de las máquinas virtuales subyacentes de Google Compute Engine. Este es un precio solo beta y aumentará una vez que el entorno flexible sea GA.

Antes de empezar

Instala el siguiente software:

Instala el componente Java de App Engine del SDK de Cloud ejecutando el siguiente comando desde la línea de comandos.

gcloud components install app-engine-java

Clonar el código de muestra

  1. Clona el código de la aplicación cliente de frontend.

    git clone https://github.com/GoogleCloudPlatform/firebase-android-client
    
  2. Clona el código del servlet de backend.

    git clone https://github.com/GoogleCloudPlatform/firebase-appengine-backend
    

Generar una huella digital SHA-1 para la aplicación

Para autenticar tu aplicación cliente para el inicio de sesión de Google, debes proporcionar una huella digital SHA-1 del certificado. En este tutorial se utiliza el almacén de claves de depuración. Para obtener información sobre cómo crear versiones de lanzamiento de la huella digital del almacén de claves, consulta el apartado sobre la autenticación de tu cliente.

  • Crea un SHA-1 de tu almacén de claves de depuración.

    keytool -exportcert -list -v \
    -alias androiddebugkey -keystore ~/.android/debug.keystore
    

Crear un proyecto de Firebase

  1. Crea una cuenta de Firebase o inicia sesión en una cuenta existente.

  2. Haz clic en Crear nuevo proyecto.

  3. En Nombre del proyecto, introduce: Playchat

  4. Selecciona Añadir Firebase a la aplicación de Android.

  5. En Nombre del paquete, introduce: com.google.cloud.solutions.flexenv

  6. En Depurar certificado de firma SHA-1, introduce el valor de SHA-1 que generaste en la sección anterior.

  7. Registra la aplicación y descarga el archivo generado, google-services.json.

  8. Anota los cambios que debes realizar en los archivos build.gradle de nivel de proyecto y de aplicación, y haz clic en Finalizar.

  9. En el menú de la izquierda de la consola de Firebase, selecciona Base de datos.

    De esta forma, se muestran los datos que almacenaste en Firebase. En los pasos posteriores de este tutorial, puedes volver a visitar esta página web para ver los datos agregados y actualizados por la aplicación cliente y el servlet de backend.

  10. Anota la URL de Firebase de tu proyecto, que tendrá el formato https://[FIREBASE_PROJECT_ID].firebaseio.com/ y aparecerá junto a un icono de enlace.

Habilitar la autenticación de Google para el proyecto de Firebase

Existen diversos proveedores de acceso que puedes configurar para que se conectarse conecten a tu proyecto de Firebase. Este tutorial te enseñará a configurar la autenticación de usuario mediante la cuenta de Google.

  1. En el menú de la izquierda de la consola de Firebase, selecciona Autenticación en el grupo Desarrollar.

  2. Haz clic en CONFIGURAR MÉTODO DE INICIO SESIÓN.

  3. Selecciona Google, activa la opción Habilitar y haz clic en Guardar.

Agregar una cuenta de servicio al proyecto de Firebase

El servlet de backend no es una persona y no tiene una cuenta de usuario de Google para iniciar sesión. En cambio, utiliza una cuenta de servicio para conectarse a Firebase. Los siguientes pasos te enseñarán a crear una cuenta de servicio que se pueda conectar a Firebase y agregar las credenciales de la cuenta de servicio al código de servlet.

  1. En el menú de la izquierda de la consola de Firebase, junto a la página principal del proyecto Playchat, selecciona la opción Ajustes y luego los permisos.

  2. Selecciona las cuentas de servicio y luego Crear cuenta de servicio.

  3. Configura las siguientes configuraciones:

    1. En Nombre de la cuenta de servicio, introduce playchat-servlet
    2. En Función, selecciona Proyecto > Propietario.

    3. Marca la opción Proporcionar una nueva clave privada.

    4. Selecciona JSON para Tipo de clave.
  4. Haz clic en Crear.

  5. Descarga el archivo de clave JSON para la cuenta de servicio y guárdalo en el proyecto de servicio de backend, firebase-appengine-backend, en el directorio src/main/webapp/WEB-INF/. El nombre de archivo tendrá el formato Playchat-[UNIQUE_ID].json.

  6. Edita src/main/webapp/WEB-INF/web.xml y los parámetros de inicialización de la siguiente manera:

    • Sustituye JSON_FILE_NAME por el nombre del archivo de clave JSON que descargaste.

    • Sustituye 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>
      

Habilitar la facturación y las API para el proyecto de Cloud Platform

Para 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 Crear un proyecto de Firebase y tiene el mismo identificador.

  1. En la consola de Cloud Platform, selecciona el proyecto de Playchat.

    Ir a la página de proyectos

  2. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

  3. Habilita las App Engine Admin API y Compute Engine API API necesarias.

    Habilita las API

Crear y desplegar el servicio de backend

El servicio de backend de este ejemplo usa una configuración Docker para especificar su entorno de alojamiento. Esta personalización significa que debes usar el entorno flexible de App Engine en lugar del entorno estándar.

Para crear el servlet de backend y desplegarlo en el entorno flexible de App Engine, puedes usar el complemento Apache Maven de App Engine del SDK de Cloud. Este complemento ya viene especificado en el archivo de compilación de Maven incluido con esta muestra.

Configurar el proyecto

Para que Maven cree el servlet de backend correctamente, debe saber en qué proyecto de Cloud Platform lanzará los recursos del servlet. El identificador de proyecto de Cloud Platform y el de Firebase son el mismo.

  1. Establece el proyecto en tu proyecto de Firebase con el siguiente comando, sustituyendo [FIREBASE_PROJECT_ID] por el nombre del ID del proyecto de Firebase que anotaste antes.

    gcloud config set project [FIREBASE_PROJECT_ID]
    
  2. Comprueba que el proyecto se ha configurado al mostrar la configuración.

    gcloud config list
    

Ejecutar el servicio en el servidor local (opcional)

Cuando estás desarrollando un nuevo servicio de backend, puede resultar útil ejecutar el servicio localmente antes de desplegarlo en App Engine. Esto hace posible iterar cambios rápidamente sin la sobrecarga de un despliegue completo en App Engine.

Al ejecutar el servidor localmente, no usa una configuración de Docker ni se ejecuta en un entorno de App Engine. En cambio, Maven garantiza que todas las bibliotecas dependientes se instalan localmente y que la aplicación se ejecuta en Jetty.

  1. En el directorio firebase-appengine-backend, crea y ejecuta localmente el módulo de backend con el siguiente comando:

    mvn clean gcloud:run
    
    mvn clean gcloud:run -Dgcloud.gcloud_directory=[PATH_TO_TOOL]
    
  2. Si te aparece el mensaje ¿Desea que la aplicación "Python.app" acepte las conexiones de red entrantes?, selecciona Permitir.

Cuando termine la implementación, abre http://localhost:8080/printLogs para verificar que el servicio de backend se está ejecutando. Verás una página web que muestra "Bandeja de entrada:" seguida 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.

A medida que actualizas la página, este identificador no cambia; tu servidor local genera una única instancia de servlet. Esto puede resultar útil durante la prueba; solo habrá un identificador de servlet almacenado en la Firebase Realtime Database.

Para cerrar el servidor local, haga clic en Control+C.

Desplegar 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 construir el entorno de alojamiento en el que se ejecuta el servicio. El entorno flexible generará varias instancias de servlet, y las ampliará y reducirá según las exigencias.

  • En el directorio firebase-appengine-backend, crea y ejecuta localmente el módulo de backend con el siguiente comando:

    mvn gcloud:deploy
    
    mvn clean gcloud:deploy -Dgcloud.gcloud_directory=[PATH_TO_GCLOUD]
    

A medida que se ejecuta la compilación, verás el mensaje "Enviando contexto de compilación al daemon de Docker..."; estos pasos cargan la configuración de Docker y la configuran en el entorno flexible de App Engine.

Cuando termine el despliegue, abre https://[FIREBASE_PROJECT_ID].appspot.com/printLogs, donde [FIREBASE_PROJECT_ID] es el identificador de Crear un proyecto de Firebase. Verás una página web que muestra "Bandeja de entrada:" seguida de un identificador de 16 dígitos. Este es el identificador de bandeja de entrada para un servlet que se ejecuta en el entorno flexible de App Engine.

A medida que actualizas la página, este identificador debe cambiar periódicamente mientras App Engine genera varias instancias de servlet para gestionar las peticiones de clientes entrantes.

Agregar Firebase y los servicios de Google Play a la aplicación de Android

La aplicación cliente utiliza la Firebase Realtime Database para almacenar y sincronizar mensajes, así como para llevar los registros de eventos del usuario. La aplicación cliente usa los servicios de Google Play para autenticar a los usuarios con su cuenta de Google.

Linux/Windows

  1. En Android Studio, selecciona Abrir un proyecto de Android Studio existente y elige el firebase-android-client.

  2. Espera a que termine de compilarse la información del proyecto de Gradle. Si se te solicita usar el contenedor de Gradle, haz clic en Aceptar.

  3. Agrega el archivo google-services.json que descargaste en Crear un proyecto de Firebase en el directorio de la app.

  4. Los cambios en los archivos build.gradle de nivel de proyecto y de aplicación que anotaste en Crear un proyecto de Firebase ya se han realizado en el código de muestra.

  5. Elige Configurar.

  6. Selecciona Administrador de SDK.

  7. En la parte superior del panel derecho, selecciona Herramientas de SDK.

  8. Asegúrate de que esté marcada la casilla de verificación junto a Servicios de Google Play.

  9. Haz clic en Aceptar.

Mac OS X

  1. En Android Studio, selecciona Abrir un proyecto de Android Studio existente y elige el firebase-android-client.

  2. Espera a que termine de compilarse la información del proyecto de Gradle. Si se te solicita usar el contenedor de Gradle, haz clic en Aceptar.

  3. Agrega el archivo google-services.json que descargaste en Crear un proyecto de Firebase en el directorio de la app.

  4. Los cambios en los archivos build.gradle de nivel de proyecto y de aplicación que anotaste en Crear un proyecto de Firebase ya se han realizado en el código de muestra.

  5. En el menú superior, selecciona Android Studio > Preferencias.

  6. Selecciona Apariencia y comportamiento > Configuración del sistema > SDK de Android.

  7. Selecciona Herramientas de SDK.

  8. Asegúrate de que esté marcada la casilla de verificación junto a Servicios de Google Play.

  9. Haz clic en Aceptar.

Ejecutar y probar la aplicación de Android

  1. En Android Studio, con el proyecto firebase-android-client abierto, selecciona Ejecutar > Ejecutar aplicación.

  2. Selecciona o crea un emulador Nexus 6 que ejecute Marshmallow (API nivel 23) como tu dispositivo de prueba.

  3. Cuando se cargue la aplicación en el emulador, inicia sesión con tu cuenta de Google.

    Iniciar sesión en Playchat

  4. Haz clic en el menú a la izquierda del título de PlayChat y selecciona el canal de libros.

    Seleccionar un canal

  5. Escribe un mensaje.

    Enviar un mensaje

  6. Cuando lo hagas, la aplicación Playchat guardará tu mensaje en la Firebase Realtime Database. Firebase sincroniza los datos almacenados en la base de datos en todos los dispositivos. Los dispositivos que ejecutan Playchat mostrarán el nuevo mensaje cuando un usuario seleccione el canal de libros.

    Enviar un mensaje

Verificar los datos

Después de que hayas utilizado la aplicación Playchat para generar algunos eventos de usuario con la aplicación Playchat, puedes verificar que los servlets se estén registrando como oyentes y recopilen registros de eventos del usuario.

Abre la Firebase Realtime Database para tu aplicación, donde [FIREBASE_PROJECT_ID] es el identificador de Crear un proyecto de Firebase.

https://console.firebase.google.com/project/[FIREBASE_PROJECT_ID]/database/data

En la parte inferior de la Firebase Realtime Database, debajo de la ubicación de datos /requestLogger/, verás una clave generada de forma aleatoria que representa el inicio de sesión de la cuenta de un usuario, por ejemplo: 1234AbCd5678EfgH90iJKlmnopQR1. Junto a él se encuentra el identificador de 16 dígitos del servlet que está escuchando actualmente los eventos de ese usuario, por ejemplo: 1782669091044729.

Datos almacenados en Firebase Realtime Database

Justo encima, debajo de la ubicación de datos /inbox/, se encuentran los identificadores de servlet para todos los servlets actualmente asignados. En este ejemplo, solo un servlet recopila registros. En /inbox/[SERVLET_IDENTIFIER] están los registros de usuario escritos por la aplicación a ese servlet.

Abre la página de App Engine para tu servicio de backend: https://[FIREBASE_PROJECT_ID].appspot.com/printLogs, donde [FIREBASE_PROJECT_ID] es el identificador de Crear un proyecto de Firebase. Cuando la página muestra el identificador para el servlet que registró los eventos del usuario que generaste, verás entradas de registro para esos eventos debajo del identificador de la bandeja de entrada del servlet.

Explorar el código

La aplicación Playchat para Android define una clase, FirebaseLogger, que usa para grabar registros de eventos de usuario en la Firebase Realtime Database.

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.cloud.solutions.flexenv.common.LogEntry;

/*
 * FirebaseLogger pushes user event logs to a specified path.
 * A backend Servlet instance listens to
 * the same key and keeps track of event logs.
 */
public class FirebaseLogger {
    private DatabaseReference logRef;
    private String tag;

    public FirebaseLogger(DatabaseReference firebase, String path) {
        logRef = firebase.child(path);
    }

    public void log(String tag, String message) {
        LogEntry entry = new LogEntry(tag, message);
        logRef.push().setValue(entry);
    }

}

Cuando un nuevo usuario inicia sesión, Playchat llama a la función requestLogger para agregar una nueva entrada a la ubicación /requestLogger/ en la Firebase Realtime Database y establece un oyente para que Playchat pueda responder cuando un servlet actualiza el valor de esa entrada, aceptando la asignación.

Cuando un servlet actualiza el valor, Playchat elimina el oyente y escribe un registro de inicio de sesión en la bandeja de entrada del servlet.

/*
 * Request that a Servlet instance be assigned.
 */
private void requestLogger() {
    firebase.child(IBX + "/" + inbox).removeValue();
    firebase.child(IBX + "/" + inbox).addValueEventListener(new ValueEventListener() {
        public void onDataChange(DataSnapshot snapshot) {
            if (snapshot.exists()) {
                fbLog = new FirebaseLogger(firebase, IBX + "/" + snapshot.getValue().toString()
                        + "/logs");
                firebase.child(IBX + "/" + inbox).removeEventListener(this);
                fbLog.log(inbox, "Signed in");
            }
        }

        public void onCancelled(DatabaseError error) {
            Log.e(TAG, error.getDetails());
        }
    });

    firebase.child(REQLOG).push().setValue(inbox);
}

En el lado del servicio de backend, cuando se inicia una instancia de servlet, la función init(ServletConfig config) en MessageProcessorServlet.java se conecta a la Firebase Realtime Database y agrega un detector a la ubicación de datos /requestLogger/.

Cuando se agrega una nueva entrada a la ubicación de datos /requestLogger/, el servlet actualiza el valor con su identificador, una señal para la aplicación Playchat de que el servlet acepta la asignación para procesar los registros para ese usuario. El servlet usa las transacciones de Firebase para garantizar que solo un servlet puede actualizar el valor y aceptar la asignación.

/*
 * Receive a request from an Android client and reply back its inbox ID.
 * Using a transaction ensures that only a single Servlet instance replies
 * to the client. This lets the client knows to which Servlet instance
 * to send consecutive user event logs.
 */
firebase.child(REQLOG).addChildEventListener(new ChildEventListener() {
  public void onChildAdded(DataSnapshot snapshot, String prevKey) {
    firebase.child(IBX + "/" + snapshot.getValue()).runTransaction(new Transaction.Handler() {
      public Transaction.Result doTransaction(MutableData currentData) {
        // The only first Servlet instance will write
        // its ID to the client inbox.
        if (currentData.getValue() == null) { currentData.setValue(inbox); }
        return Transaction.success(currentData);
      }

      public void onComplete(DatabaseError error, boolean committed, DataSnapshot snapshot) {}
    });
    firebase.child(REQLOG).removeValue();
  }

Después de que un servlet haya aceptado una asignación para procesar los registros de eventos de un usuario, añade un oyente que detecta cuándo la aplicación Playchat graba un nuevo archivo de registro en la bandeja de entrada del servlet. El servlet responde recuperando los nuevos datos de registro de la Firebase Realtime Database.

/*
 * Initialize user event logger. This is just a sample implementation to
 * demonstrate receiving updates. A production version of this application
 * should transform, filter or load to other data store such as Google BigQuery.
 */
private void initLogger() {
  String loggerKey = IBX + "/" + inbox + "/logs";
  purger.registerBranch(loggerKey);
  firebase.child(loggerKey).addChildEventListener(new ChildEventListener() {
    public void onChildAdded(DataSnapshot snapshot, String prevKey) {
      if (snapshot.exists()) {
        LogEntry entry = snapshot.getValue(LogEntry.class);
        logs.add(entry);
      }
    }

    public void onCancelled(DatabaseError error) { localLog.warning(error.getDetails()); }

    public void onChildChanged(DataSnapshot arg0, String arg1) {}

    public void onChildMoved(DataSnapshot arg0, String arg1) {}

    public void onChildRemoved(DataSnapshot arg0) {}
  });
}

Limpieza

Para evitar incurrir en cargos en tu cuenta de Google Cloud Platform por usar los recursos de este inicio rápido:

Eliminar el proyecto de Cloud Platform y Firebase

La forma más sencilla de detener los cargos de facturación es eliminar el proyecto que creaste para este tutorial. Aunque creaste el proyecto en la consola de Firebase, también puedes eliminarlo en la consola de Cloud Platform, ya que los proyectos de Firebase y Cloud Platform son el mismo.

  1. En la GCP Console, dirígete a la página Proyectos.

    Ir a la página Proyectos

  2. En la lista de proyectos, selecciona el proyecto que deseas borrar y haz clic en Borrar.
  3. En el cuadro de diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Eliminar las versiones no predeterminadas de la aplicación App Engine

Si no deseas eliminar tu proyecto de Cloud Platform y Firebase, puedes reducir los costes eliminando las versiones no predeterminadas de tu aplicación de entorno flexible de App Engine.

  1. En GCP Console, dirígete a la página Versiones de App Engine.

    Ir a la página de Versiones

  2. Haz clic en la casilla de verificación junto a la versión de app no predeterminada que deseas borrar.
  3. Haz clic en el botón Borrar en la parte superior de la página para borrar la versión de la app.

Siguientes pasos

  • Analizar y archivar datos: En este despliegue de 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, utilizando servicios como Cloud Storage, Cloud Bigtable, Google Cloud Dataflow y BigQuery.

  • Distribuir la carga de trabajo entre los servlets de manera uniforme: App Engine proporciona escalas automáticas y manuales. Con el escalado automático, el entorno flexible detecta aumentos o disminuciones en la carga de trabajo y responde al agregar o eliminar máquinas virtuales en el clúster. Con la escala manual, especificas un número estático de máquinas virtuales para gestionar el tráfico. Para obtener más información sobre cómo configurar la escala, consulta el apartado sobre la configuración de escalado del servicio en la documentación de App Engine.

    Dado que los registros de actividad del usuario se asignan a los servlets mediante el acceso a la Firebase Realtime Database, es posible que la carga de trabajo no se distribuya de manera uniforme. Por ejemplo, un servlet puede procesar más registros de eventos de usuario que otros servlets.

    Puedes mejorar la eficiencia desplegando un administrador de carga de trabajo que controle la carga de trabajo en cada máquina virtual de forma independiente. Este equilibrio de la carga de trabajo podría basarse en métricas como las peticiones de registro por segundo o la cantidad de clientes concurrentes.

  • Recuperar registros de eventos de usuario sin procesar: En este despliegue de ejemplo, si una instancia de servlet falla, la aplicación de Android asociada a ella continúa enviando eventos de registro a la bandeja de entrada del servlet en la Firebase Realtime Database. En una versión de producción de esta aplicación, el servicio de backend debe detectar esta situación para recuperar los registros de eventos de usuario sin procesar.

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...