Entérate de todos los anuncios de Firebase Summit y descubre cómo Firebase puede ayudarte a acelerar el desarrollo de las apps y a ejecutarlas con confianza. Más información

Su entorno de servidor y FCM

El lado del servidor de Firebase Cloud Messaging consta de dos componentes:

  • El backend de FCM proporcionado por Google.
  • Su servidor de aplicaciones u otro entorno de servidor de confianza donde se ejecuta la lógica de su servidor, como Cloud Functions para Firebase u otros entornos de nube administrados por Google.

Su servidor de aplicaciones o entorno de servidor de confianza envía solicitudes de mensajes al backend de FCM, que luego enruta los mensajes a las aplicaciones cliente que se ejecutan en los dispositivos de los usuarios.

Requisitos para el entorno de servidor de confianza

Su entorno de servidor de aplicaciones debe cumplir con los siguientes criterios:

  • Capaz de enviar solicitudes de mensajes con el formato correcto al backend de FCM.
  • Capaz de manejar solicitudes y reenviarlas utilizando un retroceso exponencial.
  • Capaz de almacenar de forma segura las credenciales de autorización del servidor y los tokens de registro del cliente.
  • Para el protocolo XMPP (si se usa), el servidor debe poder generar ID de mensajes para identificar de forma única cada mensaje que envía (el backend HTTP de FCM genera ID de mensajes y los devuelve en la respuesta). Los ID de mensajes XMPP deben ser únicos por ID de remitente.

Elegir una opción de servidor

Deberá decidir una forma de interactuar con los servidores de FCM: ya sea mediante el SDK de administración de Firebase o los protocolos sin formato. Debido a su compatibilidad con lenguajes de programación populares y sus métodos convenientes para manejar la autenticación y la autorización, el SDK de Firebase Admin es el método recomendado.

Las opciones para interactuar con los servidores de FCM incluyen lo siguiente:

  • El SDK de administración de Firebase, que es compatible con Node , Java , Python , C# y Go .
  • La API FCM HTTP v1 , que es la opción de protocolo más actualizada, con una autorización más segura y capacidades flexibles de mensajería multiplataforma (el SDK de administración de Firebase se basa en este protocolo y proporciona todas sus ventajas inherentes). Debido a que las nuevas funciones generalmente se agregan solo a la API HTTP v1, recomendamos usar esta API para la mayoría de los casos de uso.
  • El protocolo HTTP heredado . Se recomienda enfáticamente que los nuevos proyectos adopten la API HTTP de FCM v1 en lugar del protocolo heredado.
  • El protocolo de servidor XMPP heredado . Se recomienda enfáticamente que los nuevos proyectos adopten la API HTTP de FCM v1 en lugar del protocolo heredado.

SDK de administración de Firebase para FCM

La API de Admin FCM maneja la autenticación con el backend y facilita el envío de mensajes y la gestión de suscripciones a temas. Con el SDK de administración de Firebase, puede:

  • Enviar mensajes a dispositivos individuales
  • Envíe mensajes a temas y estados de condiciones que coincidan con uno o más temas.
  • Suscribir y cancelar la suscripción de dispositivos hacia y desde temas
  • Cree cargas útiles de mensajes adaptadas a diferentes plataformas de destino

El SDK de Admin Node.js proporciona métodos para enviar mensajes a grupos de dispositivos.

Para configurar el SDK de Firebase Admin, consulte Agregar el SDK de Firebase Admin a su servidor . Si ya tiene un proyecto de Firebase, comience con Agregar el SDK . Además, asegúrese de habilitar la API de Cloud Messaging en la página de configuración de Cloud Messaging para su proyecto. Luego, una vez que se instala el SDK de Firebase Admin, puede comenzar a escribir lógica para crear solicitudes de envío .

Protocolos del servidor FCM

Actualmente, FCM proporciona estos protocolos de servidor sin procesar:

Su servidor de aplicaciones puede usar estos protocolos por separado o en conjunto. Debido a que es la más actualizada y flexible para enviar mensajes a múltiples plataformas, se recomienda la API FCM HTTP v1 siempre que sea factible. Si sus requisitos incluyen mensajes ascendentes desde los dispositivos al servidor, deberá implementar el protocolo XMPP.

La mensajería XMPP se diferencia de la mensajería HTTP en los siguientes aspectos:

  • Mensajes ascendentes/descendentes
    • HTTP: solo descendente, de la nube al dispositivo.
    • XMPP: Upstream y downstream (de dispositivo a nube, de nube a dispositivo).
  • Mensajería (sincrónica o asincrónica)
    • HTTP: Síncrono. Los servidores de aplicaciones envían mensajes como solicitudes HTTP POST y esperan una respuesta. Este mecanismo es síncrono e impide que el remitente envíe otro mensaje hasta que se reciba la respuesta.
    • XMPP: Asíncrono. Los servidores de aplicaciones envían/reciben mensajes hacia/desde todos sus dispositivos a la máxima velocidad de línea a través de conexiones XMPP persistentes. El servidor de conexión XMPP envía notificaciones de reconocimiento o fallas (en forma de mensajes XMPP codificados con ACK y NACK JSON especiales) de forma asíncrona.
  • JSON
    • HTTP: mensajes JSON enviados como HTTP POST.
    • XMPP: mensajes JSON encapsulados en mensajes XMPP.
  • Texto sin formato
    • HTTP: mensajes de texto sin formato enviados como HTTP POST.
    • XMPP: no compatible.
  • Envío descendente de multidifusión a múltiples tokens de registro.
    • HTTP: compatible con el formato de mensaje JSON.
    • XMPP: no compatible.

Implementación del protocolo del servidor HTTP

Para enviar un mensaje, el servidor de aplicaciones emite una solicitud POST con un encabezado HTTP y un cuerpo HTTP compuesto por pares de valores clave JSON. Para obtener detalles sobre las opciones de encabezado y cuerpo, consulte Crear solicitudes de envío del servidor de aplicaciones

Implementación del protocolo del servidor XMPP

La carga útil de JSON para los mensajes de FCM es similar al protocolo HTTP, con estas excepciones:

  • No hay soporte para múltiples destinatarios.
  • FCM agrega el campo message_id , que es obligatorio. Este ID identifica de forma única el mensaje en una conexión XMPP. El ACK o NACK de FCM usa el message_id para identificar un mensaje enviado desde los servidores de aplicaciones a FCM. Por lo tanto, es importante que este message_id no solo sea único (por ID de remitente ), sino que siempre esté presente.
  • XMPP usa la clave del servidor para autorizar una conexión persistente a FCM. Consulte Autorizar solicitudes de envío para obtener más información.

Además de los mensajes regulares de FCM, se envían mensajes de control, indicados por el campo message_type en el objeto JSON. El valor puede ser 'ack' o 'nack', o 'control' (ver formatos abajo). Su servidor puede message_type cualquier mensaje de FCM con un tipo de mensaje desconocido.

Para cada mensaje de dispositivo que su servidor de aplicaciones recibe de FCM, debe enviar un mensaje ACK. Nunca necesita enviar un mensaje NACK. Si no envía un ACK para un mensaje, FCM lo vuelve a enviar la próxima vez que se establezca una nueva conexión XMPP, a menos que el mensaje caduque primero.

FCM también envía un ACK o NACK para cada mensaje de servidor a dispositivo. Si no recibe ninguno de los dos, significa que la conexión TCP se cerró en medio de la operación y su servidor necesita reenviar los mensajes. Consulte Control de flujo para obtener más detalles.

Consulte la Referencia de protocolo para obtener una lista de todos los parámetros del mensaje.

Formato de solicitud

Mensaje con carga útil: mensaje de notificación

Aquí hay una estrofa XMPP para un mensaje de notificación:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
     "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
  }
  </gcm>
</message>

Mensaje con carga útil: mensaje de datos

Aquí hay una estrofa XMPP que contiene el mensaje JSON de un servidor de aplicaciones a FCM:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

Formato de respuesta

Una respuesta FCM puede tener tres formas posibles. El primero es un mensaje regular de 'ack'. Pero cuando la respuesta contiene un error, hay 2 formas diferentes que puede tomar el mensaje, que se describen a continuación.

mensaje de acuse de recibo

Aquí hay una estrofa XMPP que contiene el mensaje ACK/NACK de FCM al servidor de aplicaciones:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

Mensaje NACK

Un error NACK es un mensaje XMPP normal en el que el mensaje de estado message_type es "nack". Un mensaje NACK contiene:

  • Un código de error NACK.
  • Una descripción de error de NACK.

A continuación se muestran algunos ejemplos.

Mal registro:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationToken",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

JSON no válido:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

Velocidad de mensajes del dispositivo excedida:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

Consulte la Referencia del servidor para obtener una lista completa de los códigos de error NACK. A menos que se indique lo contrario, no se debe volver a intentar un mensaje NACK. Los códigos de error NACK inesperados deben tratarse igual que INTERNAL_SERVER_ERROR .

error de estrofa

También puede obtener un error de estrofa en ciertos casos. Un error de estrofa contiene:

  • Código de error de la estrofa.
  • Descripción del error de estrofa (texto libre).

Por ejemplo:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

Mensajes de control

Periódicamente, FCM necesita cerrar una conexión para realizar el equilibrio de carga. Antes de cerrar la conexión, FCM envía un mensaje CONNECTION_DRAINING para indicar que la conexión se está drenando y se cerrará pronto. "Drenaje" se refiere a cerrar el flujo de mensajes que ingresan a una conexión, pero permitir que continúe lo que ya está en la tubería. Cuando recibe un mensaje de CONNECTION_DRAINING , debe comenzar a enviar mensajes de inmediato a otra conexión de FCM, abriendo una nueva conexión si es necesario. Sin embargo, debe mantener abierta la conexión original y continuar recibiendo mensajes que puedan llegar a través de la conexión (y ACK)—FCM maneja el inicio de una conexión cerrada cuando está lista.

El mensaje CONNECTION_DRAINING se ve así:

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

CONNECTION_DRAINING es actualmente el único control_type admitido.

Control de flujo

Cada mensaje enviado a FCM recibe una respuesta ACK o NACK. Los mensajes que no han recibido una de estas respuestas se consideran pendientes. Si el recuento de mensajes pendientes llega a 100, el servidor de aplicaciones debe dejar de enviar mensajes nuevos y esperar a que FCM reconozca algunos de los mensajes pendientes existentes, como se ilustra en la figura 1:

Diagrama detallado del flujo de control entre FCM y el servidor de aplicaciones

Figura 1. Flujo de mensaje/reconocimiento.

Por el contrario, para evitar sobrecargar el servidor de aplicaciones, FCM deja de enviar si hay demasiados mensajes no reconocidos. Por lo tanto, el servidor de aplicaciones debe "ACK" de los mensajes ascendentes, recibidos de la aplicación cliente a través de FCM, tan pronto como sea posible para mantener un flujo constante de mensajes entrantes. El límite de mensajes pendientes mencionado anteriormente no se aplica a estos ACK. Incluso si el recuento de mensajes pendientes llega a 100, el servidor de aplicaciones debe continuar enviando ACK para los mensajes recibidos de FCM para evitar bloquear la entrega de nuevos mensajes ascendentes.

Los ACK solo son válidos dentro del contexto de una conexión. Si la conexión se cierra antes de que se pueda acusar recibo de un mensaje, el servidor de la aplicación debe esperar a que FCM vuelva a enviar el mensaje ascendente antes de acusarlo de nuevo. De manera similar, todos los mensajes pendientes para los cuales no se recibió un ACK/NACK de FCM antes de que se cerrara la conexión deben enviarse nuevamente.