Mensajería por temas en iOS

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. Redactas tantos mensajes a temas como sea necesario y FCM maneja la ruta de los mensajes y la entrega del mensaje de manera confiable a los dispositivos correctos.

Por ejemplo, los usuarios de una app de pronóstico local de mareas podrían aceptar un tema de “alertas de corrientes de marea” y recibir notificaciones de condiciones óptimas de pesca en agua salada en áreas específicas. Los usuarios de una app de deportes se pueden suscribir a actualizaciones automáticas para obtener los resultados de juego de sus equipos favoritos en tiempo real.

Estos son algunos puntos que debes tener en cuenta sobre los 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 prácticos.

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 suscribirte a un tema, llama al método de suscripción desde el subproceso principal de la aplicación (FCM no tiene seguridad en los subprocesos). Si la solicitud de suscripción falla inicialmente, FCM vuelve a intentarlo automáticamente. Cuando la suscripción no se puede completar, esta genera un error que puedes capturar en un controlador de finalización, como se muestra a continuación:

Swift

Messaging.messaging().subscribe(toTopic: "news") { error in
  print("Subscribed to news topic")
}

Objective-C

[[FIRMessaging messaging] subscribeToTopic:@"news"
                                completion:^(NSError * _Nullable error) {
  NSLog(@"Subscribed to news topic");
}];

Esta llamada realiza una solicitud asíncrona al backend de FCM y suscribe al cliente al tema determinado. Antes de llamar a subscribeToTopic:topic, asegúrate de que la instancia de app cliente ya haya recibido un token de registro mediante la devolución de llamada didReceiveRegistrationToken.

Cada vez que la app se inicia, FCM se asegura de que todos los temas solicitados estén suscritos. Para anular la suscripción, llama a unsubscribeFromTopic:topic y FCM anulará la suscripción del tema en segundo plano.

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 por temas de la misma manera que otros mensajes descendentes.

Implementa AppDelegate application:didReceiveRemoteNotification: como se muestra a continuación:

Swift

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)

  completionHandler(UIBackgroundFetchResult.newData)
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // Print full message.
  NSLog(@"%@", userInfo);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

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 esta 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 '{
  "message": {
    "topic" : "foo-bar",
    "notification": {
      "body": "This is a Firebase Cloud Messaging Topic Message!",
      "title": "FCM Message"
    }
  }
}' 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…

¿Necesitas ayuda? Visita nuestra página de asistencia.