Envie mensagens para vários dispositivos nas plataformas Apple

Para direcionar uma mensagem para vários dispositivos, use Mensagens de tópico . Este recurso permite que você envie uma mensagem para vários dispositivos que ativaram um tópico específico.

Este tutorial se concentra no envio de mensagens de tópico do seu servidor de aplicativos usando o SDK Admin ou API REST para FCM e no recebimento e processamento delas em um aplicativo Apple. Esta página lista todas as etapas para fazer isso, desde a configuração até a verificação. Portanto, ela pode abranger as etapas que você já concluiu se configurou um aplicativo cliente Apple para FCM ou seguiu as etapas para enviar sua primeira mensagem .

Adicione o Firebase ao seu projeto Apple

Esta seção aborda tarefas que você pode ter concluído se já tiver habilitado outros recursos do Firebase para seu aplicativo. Especificamente para o FCM, você precisará carregar sua chave de autenticação de APNs e registrar-se para receber notificações remotas .

Pré-requisitos

  • Instale o seguinte:

    • Xcode 14.1 ou posterior
  • Certifique-se de que seu projeto atenda a estes requisitos:

    • Seu projeto deve ter como alvo estas versões de plataforma ou posteriores:
      • iOS 11
      • macOS 10.13
      • tvOS 12
      • watchOS 6
  • Configure um dispositivo Apple físico para executar seu aplicativo e conclua estas tarefas:

    • Obtenha uma chave de autenticação de notificação push da Apple para sua conta de desenvolvedor Apple .
    • Habilite notificações push no XCode em App > Capabilities .

Se você ainda não tem um projeto Xcode e deseja apenas testar um produto Firebase, baixe um de nossos exemplos de início rápido .

Crie um projeto do Firebase

Antes de adicionar o Firebase ao seu aplicativo Apple, você precisa criar um projeto do Firebase para se conectar ao seu aplicativo. Visite Entenda os projetos do Firebase para saber mais sobre os projetos do Firebase.

Registre seu aplicativo no Firebase

Para usar o Firebase em seu aplicativo Apple, você precisa registrar seu aplicativo em seu projeto Firebase. Registrar seu aplicativo geralmente é chamado de "adicionar" seu aplicativo ao projeto.

  1. Vá para o console do Firebase .

  2. No centro da página de visão geral do projeto, clique no ícone iOS+ para iniciar o fluxo de trabalho de configuração.

    Se você já adicionou um aplicativo ao seu projeto do Firebase, clique em Adicionar aplicativo para exibir as opções da plataforma.

  3. Insira o ID do pacote do seu aplicativo no campo ID do pacote .

  4. (Opcional) Insira outras informações do aplicativo: apelido do aplicativo e ID da App Store .

  5. Clique em Registrar aplicativo .

Adicione um arquivo de configuração do Firebase

  1. Clique em Baixar GoogleService-Info.plist para obter o arquivo de configuração das plataformas Firebase Apple ( GoogleService-Info.plist ).

  2. Mova seu arquivo de configuração para a raiz do seu projeto Xcode. Se solicitado, selecione para adicionar o arquivo de configuração a todos os destinos.

Se você tiver vários IDs de pacote no seu projeto, deverá associar cada ID de pacote a um aplicativo registrado no Console do Firebase para que cada aplicativo possa ter seu próprio arquivo GoogleService-Info.plist .

Adicione SDKs do Firebase ao seu aplicativo

Use o Swift Package Manager para instalar e gerenciar dependências do Firebase.

  1. No Xcode, com o projeto do seu aplicativo aberto, navegue até File > Add Packages .
  2. Quando solicitado, adicione o repositório SDK das plataformas Apple do Firebase:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Escolha a biblioteca Firebase Cloud Messaging.
  5. Adicione o sinalizador -ObjC à seção Outros sinalizadores de vinculador das configurações de compilação do seu destino.
  6. Para uma experiência ideal com o Firebase Cloud Messaging, recomendamos ativar o Google Analytics no seu projeto do Firebase e adicionar o SDK do Firebase para Google Analytics ao seu aplicativo. Você pode selecionar a biblioteca sem coleção IDFA ou com coleção IDFA.
  7. Quando terminar, o Xcode começará automaticamente a resolver e baixar suas dependências em segundo plano.

Faça upload da sua chave de autenticação de APNs

Faça upload da sua chave de autenticação de APNs para o Firebase. Se você ainda não possui uma chave de autenticação de APNs, crie uma no Apple Developer Member Center .

  1. Dentro do seu projeto no console do Firebase, selecione o ícone de engrenagem, selecione Configurações do projeto e selecione a guia Cloud Messaging .

  2. Na chave de autenticação APNs em configuração do aplicativo iOS , clique no botão Upload .

  3. Navegue até o local onde você salvou sua chave, selecione-o e clique em Abrir . Adicione o ID da chave (disponível no Apple Developer Member Center ) e clique em Upload .

Inicialize o Firebase no seu aplicativo

Você precisará adicionar o código de inicialização do Firebase ao seu aplicativo. Importe o módulo Firebase e configure uma instância compartilhada conforme mostrado:

  1. Importe o módulo FirebaseCore em seu UIApplicationDelegate , bem como quaisquer outros módulos Firebase que seu delegado de aplicativo usa. Por exemplo, para usar o Cloud Firestore e o Authentication:

    SwiftUI

    import SwiftUI
    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Rápido

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Objetivo-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  2. Configure uma instância compartilhada FirebaseApp no ​​método application(_:didFinishLaunchingWithOptions:) delegado do seu aplicativo:

    SwiftUI

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

    Rápido

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

    Objetivo-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. Se estiver usando SwiftUI, você deve criar um delegado de aplicativo e anexá-lo à estrutura App por meio de UIApplicationDelegateAdaptor ou NSApplicationDelegateAdaptor . Você também deve desativar o swizzling de delegado do aplicativo. Para obter mais informações, consulte as instruções do SwiftUI .

    SwiftUI

    @main
    struct YourApp: App {
      // register app delegate for Firebase setup
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
      var body: some Scene {
        WindowGroup {
          NavigationView {
            ContentView()
          }
        }
      }
    }
          

Registre-se para receber notificações remotas

Na inicialização ou no ponto desejado no fluxo do seu aplicativo, registre seu aplicativo para notificações remotas. Chame registerForRemoteNotifications conforme mostrado:

Rápido


UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
  options: authOptions,
  completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()

Objetivo-C


[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
    UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
    requestAuthorizationWithOptions:authOptions
    completionHandler:^(BOOL granted, NSError * _Nullable error) {
      // ...
    }];

[application registerForRemoteNotifications];

Inscrever o aplicativo cliente em um tópico

Os aplicativos cliente podem assinar qualquer tópico existente ou podem criar um novo tópico. Quando um aplicativo cliente assina um novo nome de tópico (um que ainda não existe para seu projeto do Firebase), um novo tópico com esse nome é criado no FCM e qualquer cliente pode subscrevê-lo posteriormente.

Para assinar um tópico, chame o método de assinatura do thread principal do seu aplicativo (FCM não é thread-safe). Se a solicitação de assinatura falhar inicialmente, o FCM tentará novamente automaticamente. Para casos em que a assinatura não pode ser concluída, a assinatura gera um erro que pode ser detectado em um manipulador de conclusão, conforme mostrado:

Rápido

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

Objetivo-C

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

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

Cada vez que o aplicativo é iniciado, o FCM garante que todos os tópicos solicitados foram inscritos. Para cancelar a assinatura, chame unsubscribeFromTopic:topic e o FCM cancela a assinatura do tópico em segundo plano.

Receber e lidar com mensagens de tópico

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

Implemente application(_:didReceiveRemoteNotification:fetchCompletionHandler:) conforme mostrado:

Rápido

func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
  -> UIBackgroundFetchResult {
  // 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)

  return UIBackgroundFetchResult.newData
}

Objetivo-C

- (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 full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

Crie solicitações de envio

Depois de criar um tópico, seja inscrevendo instâncias do aplicativo cliente no tópico no lado do cliente ou por meio da API do servidor , você poderá enviar mensagens para o tópico. Se esta for a primeira vez que você cria solicitações de envio para o FCM, consulte o guia do ambiente do seu servidor e do FCM para obter informações importantes sobre antecedentes e configuração.

Na sua lógica de envio no backend, especifique o nome do tópico desejado conforme mostrado:

Node.js

// The topic name can be optionally prefixed with "/topics/".
const topic = 'highScores';

const message = {
  data: {
    score: '850',
    time: '2:45'
  },
  topic: topic
};

// Send a message to devices subscribed to the provided topic.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// The topic name can be optionally prefixed with "/topics/".
String topic = "highScores";

// See documentation on defining a message payload.
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setTopic(topic)
    .build();

// Send a message to the devices subscribed to the provided topic.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Pitão

# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    topic=topic,
)

# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Ir

// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Topic: topic,
}

// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";

// See documentation on defining a message payload.
var message = new Message()
{
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
    Topic = topic,
};

// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

DESCANSAR

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

Comando 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

Para enviar uma mensagem para uma combinação de tópicos, especifique uma condição , que é uma expressão booleana que especifica os tópicos de destino. Por exemplo, a condição a seguir enviará mensagens para dispositivos inscritos em TopicA e TopicB ou TopicC :

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

O FCM primeiro avalia quaisquer condições entre parênteses e depois avalia a expressão da esquerda para a direita. Na expressão acima, um usuário inscrito em um único tópico não recebe a mensagem. Da mesma forma, um usuário que não assina o TopicA não recebe a mensagem. Estas combinações recebem:

  • TopicA e TopicB
  • TopicA e TopicC

Você pode incluir até cinco tópicos em sua expressão condicional.

Para enviar para uma condição:

Node.js

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';

// See documentation on defining a message payload.
const message = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  condition: condition
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
Message message = Message.builder()
    .setNotification(Notification.builder()
        .setTitle("$GOOG up 1.43% on the day")
        .setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
        .build())
    .setCondition(condition)
    .build();

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Pitão

# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
        title='$GOOG up 1.43% on the day',
        body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    ),
    condition=condition,
)

# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Ir

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Condition: condition,
}

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
var message = new Message()
{
    Notification = new Notification()
    {
        Title = "$GOOG up 1.43% on the day",
        Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
    },
    Condition = condition,
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

DESCANSAR

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

Comando 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

Próximos passos