Configurar um app cliente do Firebase Cloud Messaging com C++

Para criar um app cliente multiplataforma Firebase Cloud Messaging com C++, use a API Firebase Cloud Messaging. O SDK para C++ funciona em Android e iOS, exigindo uma instalação adicional em cada plataforma.

Configurar o Firebase e o SDK do FCM

Android

  1. Os apps cliente do FCM exigem dispositivos com Android 4.1 ou versões posteriores que tenham o app Google Play Services instalado e sejam criados com o Gradle usando Android Studio 1.4 ou versões posteriores.
  2. Adicione o Firebase ao seu projeto para C++ se ainda não tiver feito isso.
  3. No Android Studio, adicione a dependência FCM ao arquivo build.gradle no nível do aplicativo:
    repositories {
    flatDir {
    dirs project.ext.firebase_cpp_sdk_dir + "/libs/android"
    }
    }
    dependencies {
     implementation 'com.google.firebase:firebase-messaging:17.4.0'
     implementation 'com.google.firebase.messaging.cpp:firebase_messaging_cpp@aar'
    }
  4. Vincule as bibliotecas estáticas libapp.a e libmessaging.a por meio do SDK para C++.
  5. Crie um objeto do app Firebase, transferindo o ambiente JNI e a atividade:
    app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);
    
  6. Defina uma classe que implementa a interface firebase::messaging::Listener.
  7. Inicialize o Firebase Cloud Messaging, transferindo o App e um Listener criado:
    ::firebase::messaging::Initialize(app, listener);
    
  8. Os apps que contam com o SDK do Google Play Services devem sempre verificar se há um APK do Google Play Services compatível no dispositivo antes de acessar os recursos. Para saber mais, consulte Verificar a existência de APK do Google Play Services.

iOS

  1. Você precisa de um certificado de APNs válido. Se você não tiver um, consulte Aprovisionar certificados SSL para APNs.
  2. Adicione o Firebase ao seu projeto para C++ se ainda não tiver feito isso.
  3. No Podfile do projeto, adicione a dependência do FCM:
    pod 'Firebase/Messaging'
  4. Arraste as bibliotecas firebase.framework e firebase_messaging.framework para seu projeto do Xcode por meio do SDK para C++.
  5. Configure o projeto do Xcode para ativar as notificações push:
    1. Selecione o projeto no painel de navegação.
    2. Selecione o destino do projeto em Editor.
    3. Selecione a guia General em Editor.
    4. Role para baixo até Linked Frameworks and Libraries e clique no botão com o símbolo + para adicionar uma biblioteca.
      • Na janela exibida, role até UserNotifications.framework e clique nessa entrada. Depois, clique em Add. Essa biblioteca só aparecerá no Xcode versão 8 e posterior, conforme exigido.
    5. Selecione a guia Capabilities em Editor.
    6. Mude Push Notifications para On.
    7. Role para baixo até Background Modes e mude para On.
    8. Marque a caixa Remote notifications em Background Modes.
  6. Crie um objeto do aplicativo Firebase:
    app = ::firebase::App::Create(::firebase::AppOptions());
  7. Defina uma classe que implementa a interface firebase::messaging::Listener.
  8. Inicialize o Firebase Cloud Messaging, transferindo o app e um listener construído:
    ::firebase::messaging::Initialize(app, listener);

Acessar o token de registro do dispositivo

Na inicialização da biblioteca do Firebase Cloud Messaging, um token de registro é solicitado para a instância do app cliente. O app receberá o token com o retorno de chamada OnTokenReceived, que deve ser definido na classe que implementa firebase::messaging::Listener.

Para direcionar o app para esse dispositivo específico, você precisará ter acesso a esse token.

Observação sobre entrega de mensagens no Android

Quando o aplicativo não está em execução e um usuário toca em uma notificação, por padrão, a mensagem não é encaminhada por meio dos retornos de chamada incorporados do FCM. Nesse caso, os payloads das mensagens são recebidos por meio de um Intent usado para iniciar o aplicativo. Para que o FCM encaminhe essas mensagens recebidas para o retorno de chamada da biblioteca C++, é necessário modificar o método onNewIntent em sua atividade e passar Intent para MessageForwardingService.

import com.google.firebase.messaging.MessageForwardingService;

class MyActivity extends Activity {
  private static final String TAG = "MyActvity";

  @Override
  protected void onNewIntent(Intent intent) {
    Log.d(TAG, "A message was sent to this app while it was in the background.");
    Intent message = new Intent(this, MessageForwardingService.class);
    message.setAction(MessageForwardingService.ACTION_REMOTE_INTENT);
    message.putExtras(intent);
    message.setData(intent.getData());
    startService(message);
  }
}

As mensagens recebidas enquanto o aplicativo está em segundo plano têm o conteúdo do campo de notificação usado para preencher a notificação da bandeja do sistema, mas esse conteúdo não será comunicado ao FCM. Ou seja, Message::notification será nulo.

Em resumo:

Estado do app Notificação Dados Ambos
Primeiro plano OnMessageReceived OnMessageReceived OnMessageReceived
Segundo plano Bandeja do sistema OnMessageReceived Notificação: bandeja do sistema
Dados: nos extras do intent

Processamento de mensagens personalizadas no Android

Por padrão, as notificações enviadas para o app são passadas para ::firebase::messaging::Listener::OnMessageReceived, mas, em alguns casos, talvez você queira modificar o comportamento padrão. Para fazer isso no Android, é necessário escrever classes personalizadas que ampliam com.google.firebase.messaging.cpp.ListenerService, além de atualizar o AndroidManifest.xml do seu projeto.

Modificar os métodos ListenerService

O ListenerService é a classe Java que intercepta as mensagens recebidas enviadas para o app e as encaminha para a biblioteca C ++. Quando o app está em primeiro plano (ou em segundo plano e recebe um payload somente de dados), as mensagens são transmitidas por meio de um dos retornos de chamada fornecidos nessa classe. Para adicionar um comportamento personalizado ao processamento de mensagens, será necessário estender o ListenerService padrão do FCM:

import com.google.firebase.messaging.cpp.ListenerService;

class MyListenerService extends ListenerService {

Ao modificar o método ListenerService.onMessageReceived, é possível executar ações com base no objeto RemoteMessage recebido e acessar os dados das mensagens:

@Override
public void onMessageReceived(RemoteMessage message) {
  Log.d(TAG, "A message has been received.");
  // Do additional logic...
  super.onMessageReceived(message);
}

ListenerService também tem alguns outros métodos que são usados com menos frequência e que também podem ser modificados. Para mais informações, consulte a referência de FirebaseMessagingService.

@Override
public void onDeletedMessages() {
  Log.d(TAG, "Messages have been deleted on the server.");
  // Do additional logic...
  super.onDeletedMessages();
}

@Override
public void onMessageSent(String messageId) {
  Log.d(TAG, "An outgoing message has been sent.");
  // Do additional logic...
  super.onMessageSent(messageId);
}

@Override
public void onSendError(String messageId, Exception exception) {
  Log.d(TAG, "An outgoing message encountered an error.");
  // Do additional logic...
  super.onSendError(messageId, exception);
}

Atualizar AndroidManifest.xml

Com suas classes personalizadas já escritas, é necessário incluí-las no AndroidManifest.xml para que tenham efeito. O manifesto precisa incluir as ferramentas de mesclagem declarando o atributo adequado dentro da tag <manifest> da seguinte maneira:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.firebase.messaging.cpp.samples"
    xmlns:tools="http://schemas.android.com/tools">

No arquivo firebase_messaging_cpp.aar, há um arquivo AndroidManifest.xml que declara o ListenerService padrão do FCM. Normalmente, esse manifesto é mesclado com o manifesto específico do projeto, o que permite a execução de ListenerService. Esse ListenerService precisa ser substituído pelo serviço de listener personalizado. Isso é feito com a remoção do ListenerService padrão e a adição do serviço personalizado, o que pode ser feito com as seguintes linhas no arquivo AndroidManifest.xml do seu projeto:

<service android:name="com.google.firebase.messaging.cpp.ListenerService"
         tools:node="remove" />
<service android:name="com.google.firebase.messaging.cpp.samples.MyListenerService"
         android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT"/>
  </intent-filter>
</service>

Impedir a inicialização automática

O FCM gera um código de instância, que é usado como um token de registro no FCM. Quando ele é gerado, a biblioteca faz upload dos dados de configuração e do identificador para o Firebase. Se você quer receber uma confirmação antes de usar o código da instância, é possível impedir a geração dele desativando o FCM (e, no Android, o Analytics). Para isso, adicione um valor de metadados ao seu Info.plist (não ao seu GoogleService-Info.plist) no iOS ou ao seu AndroidManifest.xml no Android:

Android

<?xml version="1.0" encoding="utf-8"?>
<application>
  <meta-data android:name="firebase_messaging_auto_init_enabled"
             android:value="false" />
  <meta-data android:name="firebase_analytics_collection_enabled"
             android:value="false" />
</application>

iOS

FirebaseMessagingAutoInitEnabled = NO

Para reativar o FCM, é possível fazer uma chamada de tempo de execução:

::firebase::messaging::SetTokenRegistrationOnInitEnabled(true);

Depois de definido, esse valor persiste às reinicializações do app.

O FCM permite que mensagens sejam enviadas contendo um link direto para seu aplicativo. Para receber mensagens que contenham um link direto, você precisa adicionar um novo filtro de intent à atividade que processa links diretos para seu aplicativo. O filtro de intent precisa capturar links diretos do seu domínio. Se as suas mensagens não contiverem um link direto, essa configuração não será necessária. No AndroidManifest.xml:

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="http"/>
  <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="https"/>
</intent-filter>

Também é possível especificar um caractere curinga para deixar o filtro de intent mais flexível. Exemplo:

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:host="*.example.com" android:scheme="http"/>
  <data android:host="*.example.com" android:scheme="https"/>
</intent-filter>

Quando os usuários tocam em uma notificação que contém um link para o esquema e o host especificados por você, seu aplicativo iniciará a atividade com esse filtro de intent para processar o link.

Próximas etapas

Quando o app cliente estiver configurado, estará tudo pronto para começar a enviar mensagens downstream e mensagens de tópico com o Firebase. Para saber mais, veja essa funcionalidade demonstrada no exemplo de início rápido, que você pode transferir por download, executar e avaliar.

Para adicionar outros comportamentos avançados ao seu app, consulte os guias para envio de mensagens de um servidor de app:

Lembre-se de que você precisa de uma implementação de servidor para usar esses recursos.

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.