Ir para o console

Enviar mensagens para tópicos no iOS

Dependendo do modelo de publicação/assinatura, as mensagens de tópico do FCM permitem que você envie uma mensagem a vários dispositivos que assinaram um tópico específico. Você escreve as mensagens em tópicos conforme necessário, e o FCM processa de maneira confiável o encaminhamento e a entrega delas aos dispositivos certos.

Por exemplo, os usuários de um aplicativo de previsão de marés podem assinar um tópico de "alertas de correntes de maré" e receber notificações das melhores condições de pesca em água salgada em áreas específicas. Os usuários de um app sobre esportes podem assinar atualizações automáticas de placares de jogos em tempo real dos times favoritos.

Alguns lembretes sobre os tópicos:

  • As mensagens em tópicos são mais adequadas a conteúdo de clima ou outras informações disponibilizadas publicamente.
  • As mensagens em tópicos são otimizadas para capacidade, não para latência. Para enviar mensagens com rapidez e segurança para dispositivos únicos ou pequenos grupos de dispositivos, segmente-as para tokens em vez de tópicos.
  • Se for necessário enviar mensagens a vários dispositivos por usuário, use as mensagens para grupos de dispositivos.
  • As mensagens em tópicos permitem um número ilimitado de assinaturas para cada tópico. No entanto, o FCM impõe limites nessas áreas:
    • Uma instância de app pode assinar no máximo 2.000 tópicos.
    • Se você estiver usando a importação em lote para assinar instâncias de app, cada solicitação estará limitada a 1.000 instâncias.
    • A frequência de novas assinaturas é limitada por projeto. Se você enviar muitas solicitações de assinatura em um curto período de tempo, os servidores FCM responderão com uma resposta 429 RESOURCE_EXHAUSTED ("cota excedida"). Tente novamente com retirada exponencial.

Inscrever o app cliente em um tópico

Os apps cliente podem ser inscritos em qualquer tópico existente ou podem criar um novo tópico. Quando um app cliente se inscreve em um novo nome de tópico que ainda não existe no seu projeto do Firebase, um novo tópico com esse nome será criado no FCM, e qualquer cliente poderá se inscrever nele posteriormente.

Para se inscrever em um tópico, chame o método de inscrição na thread principal do seu aplicativo. Lembre-se de que o FCM não é thread-safe. Se a solicitação de inscrição falhar, o FCM repetirá a tentativa automaticamente. Nos casos em que a inscrição não pode ser concluída, ela emite um erro que você pode capturar em um manipulador de conclusão, conforme mostrado abaixo:

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");
}];

Essa chamada cria uma solicitação assíncrona ao back-end do FCM e inscreve o cliente no tópico. Antes de chamar o subscribeToTopic:topic, verifique se a instância do app cliente já recebeu um token de registro por meio do retorno de chamada didReceiveRegistrationToken.

Sempre que o app for iniciado, o FCM garantirá que todos os tópicos solicitados estejam inscritos. Se você quiser cancelar a inscrição, chame unsubscribeFromTopic:topic para que o FCM cancele a inscrição do tópico em segundo plano.

Gerenciar inscrições em tópicos no servidor

Você pode aproveitar as APIs Instance ID para executar tarefas básicas de gerenciamento de tópicos no servidor. Com os tokens de registro de instâncias de apps cliente, é possível realizar estas ações:

Receber e administrar mensagens de tópico

O FCM entrega as mensagens de tópico da mesma maneira que as outras mensagens downstream.

Implemente AppDelegate application:didReceiveRemoteNotification: como mostrado:

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);
}

Criar solicitações de envio

O envio de mensagens a um tópico do Firebase Cloud Messaging é muito semelhante ao envio a um dispositivo individual ou a um grupo de usuários. No servidor de apps, a chave topic no corpo da mensagem é definida com um valor como yourTopic. Os desenvolvedores podem escolher qualquer nome de tópico que corresponda à expressão regular: "[a-zA-Z0-9-_.~%]+".

Para enviar combinações de vários tópicos, a chave condition é definida como uma condição booleana que especifica os tópicos de destino no servidor do app. Por exemplo, para enviar mensagens para dispositivos que se inscreveram no TopicA e também no TopicB ou TopicC:

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

Primeiramente, o FCM avalia todas as condições entre parênteses. Em seguida, ele avalia a expressão da esquerda para a direita. Na expressão acima, um usuário que se inscreveu em um só tópico não receberá a mensagem. Do mesmo modo, um usuário que não se inscreveu no TopicA também não receberá a mensagem. As seguintes combinações receberão a mensagem:

  • TopicA e TopicB
  • TopicA e TopicC

Você pode incluir até cinco tópicos em sua expressão condicional, e parênteses são aceitos. Operadores aceitos: &&, ||, !. Observe o uso para !:

!('TopicA' in topics)

Com essa expressão, todas as instâncias do app que não estão inscritas no TopicA recebem a mensagem, inclusive as que não estão inscritas em nenhum tópico.

Para mais detalhes sobre chaves do servidor do app, consulte as informações de referência.

Solicitação HTTP POST de tópico

Enviar para um único tópico:

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"
      }
   }
}

Enviar com 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

Enviar para dispositivos inscritos nos tópicos "dogs" ou "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",
    }
  }
}

Enviar com 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

Resposta HTTP de tópico

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

Para a lista completa de opções de mensagens, consulte a referência da API HTTP v1.

Próximas etapas