Mensajes por temas en Android

Los mensajes por temas de FCM se basan en el modelo de publicación y suscripción. Este método permite enviar un mensaje a varios dispositivos que hayan aceptado un tema específico. Tú redactas los mensajes por temas según sea necesario y FCM administra el enrutamiento y la entrega de los mensajes de manera confiable a los dispositivos correctos.

Por ejemplo, los usuarios de una app de pronóstico local del tiempo podrían aceptar un tema de "alertas de clima extremo" y recibir notificaciones de tormentas que amenacen áreas específicas. Los usuarios de una app de deportes se pueden suscribir a actualizaciones automáticas para recibir los resultados de los partidos de sus equipos favoritos en vivo.

Estos son algunos puntos para tener en cuenta cuando usas temas:

  • Los mensajes por temas admiten una cantidad ilimitada de temas y de suscripciones para cada app.
  • Los mensajes por temas son ideales para contenido como noticias, el tiempo y otra información disponible de manera pública.
  • Los mensajes por temas están optimizados en términos de rendimiento, no de latencia. Para enviar mensajes con rapidez y de manera segura a dispositivos individuales o a un grupo pequeño de dispositivos, orienta los mensajes por tokens de registro en lugar de temas.
  • Si necesitas enviar mensajes a varios dispositivos por usuario, tal vez sea más conveniente enviar mensajes a grupos de dispositivos en esos casos.

Suscribe la app cliente a un tema

Las apps cliente se pueden suscribir a cualquier tema existente o pueden crear un tema nuevo. Cuando una app cliente se suscribe a un nombre de tema nuevo (uno que no existe aún para tu proyecto de Firebase), se crea un tema nuevo con ese nombre en FCM y cualquier cliente se puede suscribir a él posteriormente.

Para suscribirse a un tema, la app cliente llama a subscribeToTopic() de Firebase Cloud Messaging con el nombre del tema de FCM:

FirebaseMessaging.getInstance().subscribeToTopic("news");

Para anular la suscripción, la app cliente invoca unsubscribeFromTopic() en Firebase Cloud Messaging con el nombre del tema.

Administra suscripciones a temas en el servidor

Puedes aprovechar las API de Instance ID para hacer tareas básicas de administración de temas desde el servidor. Con el token de registro de las instancias de la app cliente, puedes hacer lo siguiente:

Recibe y administra mensajes por temas

FCM entrega mensajes a temas de la misma manera que otros mensajes descendentes.

Para recibir mensajes, usa un servicio que extienda el FirebaseMessagingService. Tu servicio debe anular las devoluciones de llamada onMessageReceived y onDeletedMessages. Debe administrar cualquier mensaje en un plazo de 10 segundos desde su recepción. Después de eso, Android no garantiza la ejecución y podría finalizar el proceso en cualquier momento. Si tu app necesita más tiempo para procesar un mensaje, usa Firebase Job Dispatcher.

onMessageReceived se proporciona para la mayoría de los tipos de mensajes, con las siguientes excepciones:

  • Mensajes de notificación enviados cuando la app está en segundo plano. En este caso, la notificación se entrega a la bandeja del sistema del dispositivo. Cuando un usuario presiona una notificación, abre el selector de aplicaciones de forma predeterminada.

  • Mensajes con cargas útiles de notificación y de datos, tanto en primer plano como en segundo. En este caso, la notificación se entrega a la bandeja del sistema del dispositivo y la carga de datos se entrega en los adicionales del intent de tu actividad iniciadora.

Resumen:

Estado de la app Notificación Datos Ambos
Primer plano onMessageReceived onMessageReceived onMessageReceived
Segundo plano Bandeja del sistema onMessageReceived Notificación: Bandeja del sistema
Datos: En extras del intent.
Para obtener más información acerca de los tipos de mensajes, consulta Mensajes de notificación y de datos.

Edita el manifiesto de la app

Para usar FirebaseMessagingService, debes agregar lo siguiente al manifiesto de tu app:

<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

Además, te recomendamos establecer valores predeterminados para personalizar el aspecto de las notificaciones. Puedes especificar un ícono y un color predeterminados y personalizados que se aplican cada vez que no se establecen valores equivalentes en la carga útil de notificación.

Agrega estas líneas en la etiqueta application para establecer el ícono predeterminado y el color personalizado:

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

Android muestra el ícono predeterminado personalizado para lo siguiente:

  • Todos los mensajes de notificación enviados desde el compositor de Notifications.
  • Todos los mensajes de notificación que no establecen el ícono de manera explícita en la carga útil de la notificación.

Android usa el color predeterminado personalizado para lo siguiente:

  • Todos los mensajes de notificación enviados desde el compositor de Notifications.
  • Todos los mensajes de notificación que no definen el color de manera explícita en la carga útil de la notificación.

Si no hay un ícono predeterminado personalizado y no se establece un ícono en la carga útil de la notificación, Android muestra el ícono de la aplicación en blanco.

Anula onMessageReceived

Puedes anular el método FirebaseMessagingService.onMessageReceived para realizar acciones según el objeto RemoteMessage recibido y obtener los datos del mensaje:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // ...

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Anula onDeletedMessages

En algunas situaciones, es posible que FCM no envíe un mensaje. Esto ocurre cuando hay muchos mensajes (más de 100) pendientes para tu app en un dispositivo específico al momento de conectarse o si el dispositivo no se conecta a FCM en más de un mes. En estos casos, es posible que recibas una devolución de llamada a FirebaseMessagingService.onDeletedMessages(). Cuando la instancia de app recibe esta devolución de llamada, debería ejecutar una sincronización completa con tu servidor de apps. Si no enviaste un mensaje a la app en ese dispositivo en las últimas 4 semanas, FCM no llamará a onDeletedMessages().

Maneja mensajes de notificación en una app en segundo plano

Cuando tu app está en segundo plano, Android dirige los mensajes de notificación a la bandeja del sistema. Cuando un usuario presiona una notificación, se abre el selector de aplicaciones de forma predeterminada.

Esto incluye los mensajes que contienen carga útil de notificaciones y datos (y todos los mensajes que se envíen desde la consola de Notifications). En estos casos, la notificación se entrega a la bandeja del sistema del dispositivo y la carga de datos se entrega en los adicionales del intent de tu actividad iniciadora.

Crea solicitudes de envío

Enviar mensajes a un tema de Firebase Cloud Messaging es muy similar a enviar mensajes a un dispositivo individual o a un grupo de usuarios. El servidor de apps configura la clave topic en el cuerpo del mensaje con un valor como yourTopic. Los desarrolladores pueden elegir cualquier nombre de tema que coincida con la expresión regular: "[a-zA-Z0-9-_.~%]+".

Para enviar mensajes a combinaciones de varios temas, el servidor de apps establece la clave condition como una condición booleana que especifica los temas de destino. Por ejemplo, para enviar mensajes a dispositivos suscritos a TopicA y a TopicB o TopicC:

'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)

En primer lugar, FCM evalúa las condiciones en paréntesis y, luego, evalúa la expresión de izquierda a derecha. En la expresión que se observa en este ejemplo, los usuarios suscritos a uno solo de los temas no recibirán el mensaje. Asimismo, los usuarios que no estén suscritos a TopicA tampoco lo recibirán. Las siguientes combinaciones sí lo reciben:

  • TopicA y TopicB
  • TopicA y TopicC

Puedes incluir hasta cinco temas en tu expresión condicional y se admiten paréntesis. Operadores compatibles: &&, ||, !. Ten en cuenta el uso de !:

!('TopicA' in topics)

Con esta expresión, todas las instancias que no se suscriben a TopicA, incluidas las instancias de app que no se suscriben a ningún tema, reciben el mensaje.

Para obtener más detalles sobre las claves del servidor de apps, consulta la información de referencia.

Solicitud HTTP POST del tema

Envía a un tema individual:

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
      }
   }
}

Envía con cURL:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "topic" : "foo-bar"
}' "https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1"

Envía a dispositivos suscritos a los temas "dogs" o "cats":

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
   "message":{
    "condition": "'dogs' in topics || 'cats' in topics",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
    }
  }
}

Envía con cURL:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "condition": "'dogs' in topics || 'cats' in topics"
}' "https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1"

Respuesta HTTP del tema

{
    "name": "projects/myproject-b5ae1/messages/5735743068807585451"
}

Para ver la lista completa de opciones de mensaje, consulta la referencia de la API de HTTP v1.

Próximos pasos

Enviar comentarios sobre...

Si necesitas ayuda, visita nuestra página de asistencia.