Envía mensajes a varios dispositivos en iOS

Firebase Cloud Messaging brinda dos maneras de enviar un mensaje a varios dispositivos:

  • Los mensajes por tema, que permiten enviar un mensaje a varios dispositivos que hayan aceptado un tema específico.
  • Los mensajes por grupos de dispositivos, que te permiten enviar un mensaje a varias instancias de una app que se ejecute en varios dispositivos de un grupo.

Este instructivo se enfoca en el envío de mensajes por tema desde tu servidor de apps mediante los protocolos HTTP o XMPP para FCM, así como en la recepción y administración de ellos en una app de iOS. En esta página, se indican todos los pasos necesarios para lograrlo, desde la configuración hasta la verificación, por lo que es posible que ya hayas realizado algunos de los pasos si configuraste una app cliente en iOS para FCM o si ya enviaste tu primer mensaje.

Agrega Firebase a tu proyecto de iOS

Es posible que hayas completado tareas que aparecen en esta sección si ya habilitaste otras funciones de Firebase para tu app. En el caso de FCM, deberás subir tu clave de autenticación del APNS y registrarte para habilitar las notificaciones remotas.

Requisitos previos

Antes de comenzar, debes configurar lo siguiente en el entorno:

  • Xcode 9.4.1 o una versión posterior
  • un proyecto de Xcode para iOS 8 o una versión posterior
  • los proyectos Swift deben usar la versión 3.0 o una más reciente
  • el identificador del paquete de la app
  • CocoaPods 1.4.0 o una versión más reciente
  • Para Cloud Messaging:
    • un dispositivo iOS físico
    • una clave de autenticación de notificaciones push de Apple para tu cuenta de desarrollador de Apple
    • en Xcode, habilita las notificaciones push en App > Capabilities

Si aún no tienes un proyecto de Xcode, puedes descargar una de nuestras muestras de inicio rápido si solo quieres probar una función de Firebase. Si usas un inicio rápido, recuerda obtener el identificador de paquete en la configuración del proyecto, ya que lo necesitarás en el próximo paso.

Agrega Firebase a la app

Es hora de agregar Firebase a la app. Primero, necesitarás un proyecto y un archivo de configuración de Firebase para la app.

Para crear un proyecto de Firebase:

  1. Dirígete a Firebase console.

  2. Haz clic en Agregar proyecto, luego selecciona o ingresa un Nombre del proyecto.

    • Si hay un proyecto de Google existente asociado con tu app, selecciónalo desde el menú desplegable Nombre del proyecto.
    • Si no hay un proyecto de Google existente, ingresa un nuevo Nombre del proyecto.
  3. Opcional: Edita el ID del proyecto.

    Firebase asignará de manera automática un ID único a tu proyecto de Firebase. Este identificador se muestra en los servicios de Firebase visibles de forma pública, por ejemplo:

    • URL predeterminada de Realtime Database: your-project-id.firebaseio.com
    • Nombre predeterminado del depósito de Cloud Storage: your-project-id.appspot.com
    • Subdominio predeterminado de Hosting: your-project-id.firebaseapp.com
  4. Sigue los pasos de configuración restantes y, luego, haz clic en Crear proyecto (o Agregar Firebase si usas un proyecto de Google existente).

Firebase aprovisiona los recursos para tu proyecto de forma automática. Este proceso suele tardar algunos minutos. Cuando finalice, verás la página de descripción general del proyecto en Firebase console.

Ahora que tienes un proyecto, puedes agregar la app para iOS:

  1. Haz clic en Agrega Firebase a tu app para iOS y sigue los pasos de configuración. Si importas un proyecto de Google existente, es posible que esto ocurra de forma automática y solo tengas que descargar el archivo de configuración.

  2. Ingresa el ID del paquete de la app cuando se te solicite. Es importante que ingreses el ID del paquete que usa la app. Esta configuración solo puede hacerse cuando agregas la app al proyecto de Firebase.

  3. Agrega el archivo de configuración de Firebase para iOS a la app, como se indica a continuación:

    1. Haz clic en Descargar GoogleService-Info.plist a fin de obtener el archivo de configuración de Firebase para iOS (GoogleService-Info.plist).

      Puedes volver a descargar el archivo de configuración de Firebase para iOS cuando quieras.

    2. Traslada el archivo de configuración al directorio raíz de tu proyecto de Xcode. Si se te solicita, selecciona la opción para agregar el archivo de configuración a todos los objetivos.

  4. Después de agregar el código de inicialización, ejecuta tu app para verificar con la consola que instalaste Firebase correctamente.

Agrega el SDK

Si estás configurando un proyecto nuevo, debes instalar el SDK. Es posible que ya lo hayas hecho como parte de la creación de un proyecto de Firebase.

Te recomendamos que uses CocoaPods para instalar las bibliotecas. Para instalar el sistema, sigue las instrucciones. Si prefieres no usarlo, puedes integrar los marcos de trabajo del SDK directamente sin usar CocoaPods.

Si vas a descargar y ejecutar una de las muestras de inicio rápido, estas ya contienen el proyecto de Xcode y el Podfile, pero de todas formas deberás instalar los pods y descargar el archivo GoogleService-Info.plist. Si quieres integrar las bibliotecas de Firebase en uno de tus proyectos, debes agregar los pods para las bibliotecas que vayas a usar.

  1. Si aún no tienes un proyecto de Xcode, crea uno ahora.

  2. Crea un Podfile si aún no tienes uno:

    $ cd your-project directory
    $ pod init
    
  3. Agrega los pods que quieras instalar. Puedes incluir un pod en el Podfile, de la siguiente forma:

    pod 'Firebase/Core'
    pod 'Firebase/Messaging'
    

    Esto agregará las bibliotecas necesarias para comenzar a usar Firebase en la app de iOS junto con Google Analytics para Firebase. A continuación, podrás encontrar una lista de las subespecificaciones y los pods que están disponibles. Esto también se aborda en las guías de configuración específicas de cada característica.

  4. Instala los pods y abre el archivo .xcworkspace para ver el proyecto en Xcode.

    $ pod install
    $ open your-project.xcworkspace
    
  5. Descarga un archivo GoogleService-Info.plist de Firebase console y agrégalo a tu app.

Sube tu clave de autenticación del APNS

Sube la clave de autenticación del APNS a Firebase. Si aún no tienes una clave de autenticación del APN, consulta cómo configurar el APN con FCM.

  1. Dentro del proyecto en Firebase console, selecciona el ícono de ajustes, elige Configuración del proyecto y, luego, la pestaña Cloud Messaging.

  2. En Clave de autenticación del APN, bajo configuración de app de iOS, haz clic en el botón Subir.

  3. Busca la ubicación donde guardaste la clave, selecciónala y haz clic en Abrir. Agrega el ID de clave correspondiente (disponible en Certificados, identificadores y perfiles en el Centro de miembros desarrolladores de Apple) y haz clic en Subir.

Inicializa Firebase en tu app

Debes agregar el código de inicialización de Firebase a tu aplicación. Importa el módulo de Firebase y configura una instancia compartida de la siguiente manera:

  1. Importa el módulo de Firebase en tu UIApplicationDelegate:

    Swift

    import Firebase
    

    Objective-C

    @import Firebase;
    
  2. Configura una instancia compartida de FirebaseApp, generalmente en el método application:didFinishLaunchingWithOptions: de la aplicación:

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()
    

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
    

Regístrate para habilitar las notificaciones remotas

Durante el inicio o en el punto que desees del flujo de tu aplicación, registra tu app para habilitar las notificaciones remotas. Llama a registerForRemoteNotifications de la siguiente manera:

Swift

if #available(iOS 10.0, *) {
  // For iOS 10 display notification (sent via APNS)
  UNUserNotificationCenter.current().delegate = self

  let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
  UNUserNotificationCenter.current().requestAuthorization(
    options: authOptions,
    completionHandler: {_, _ in })
} else {
  let settings: UIUserNotificationSettings =
  UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
  application.registerUserNotificationSettings(settings)
}

application.registerForRemoteNotifications()

Objective-C

if ([UNUserNotificationCenter class] != nil) {
  // iOS 10 or later
  // For iOS 10 display notification (sent via APNS)
  [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
      UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
  [[UNUserNotificationCenter currentNotificationCenter]
      requestAuthorizationWithOptions:authOptions
      completionHandler:^(BOOL granted, NSError * _Nullable error) {
        // ...
      }];
} else {
  // iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
  UIUserNotificationType allNotificationTypes =
  (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
  UIUserNotificationSettings *settings =
  [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
  [application registerUserNotificationSettings:settings];
}

[application registerForRemoteNotifications];

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: "weather") { error in
  print("Subscribed to weather topic")
}

Objective-C

[[FIRMessaging messaging] subscribeToTopic:@"weather"
                                completion:^(NSError * _Nullable error) {
  NSLog(@"Subscribed to weather 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.

Recibe y administra mensajes a 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 establece la clave to con el valor /topics/yourTopic. Los desarrolladores pueden elegir cualquier nombre de tema que coincida con la expresión regular "/topics/[a-zA-Z0-9-_.~%]+".

Para enviar mensajes a combinaciones de varios temas, el servidor de apps debe configurar la clave condition (en lugar de la clave to) como una condición booleana que especifique 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 de servidor de apps, consulta la información de referencia sobre el protocolo del servidor de conexiones HTTP o XMPP que seleccionaste. Los ejemplos de esta página muestran cómo enviar mensajes a temas mediante los protocolos respectivos.

Solicitud HTTP POST del tema

Envía a un tema individual:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}

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

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "condition": "'dogs' in topics || 'cats' in topics",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}

Respuesta HTTP del tema

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}

Mensaje XMPP del tema

Envía a un tema individual:

<message id="">
  <gcm xmlns="google:mobile:data">

{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}
  </gcm>
</message>

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

<message id="">
  <gcm xmlns="google:mobile:data">

{
  "condition": "'dogs' in topics || 'cats' in topics",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}
  </gcm>
</message>

Respuesta XMPP del tema

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}

Cuando realizas una solicitud de envío por temas, pueden pasar hasta 30 segundos antes de que el servidor de FCM muestre una respuesta de ejecución correcta o con errores. Asegúrate de configurar el valor de tiempo de espera del servidor de apps en la solicitud de manera acorde.

Para ver la lista completa de opciones de mensaje, consulta la información de referencia del protocolo de servidor de conexiones que seleccionaste, HTTP o XMPP.

Pasos siguientes

Enviar comentarios sobre…

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