Configura una app cliente de Firebase Cloud Messaging con C++

Para escribir tu app cliente multiplataforma de Firebase Cloud Messaging con C++, usa la API de Firebase Cloud Messaging. El SDK de C++ funciona con las plataformas de Android y Apple, pero se necesitan algunos pasos de configuración adicionales en cada plataforma.

Configura Firebase y el SDK de FCM

Android

  1. Si aún no lo has hecho, agrega Firebase a tu proyecto de C++.

    • En las instrucciones de configuración vinculadas, revisa los requisitos del dispositivo y la para usar el SDK de Firebase C++, incluidas las recomendaciones de compilación de apps con CMake.

    • En tu archivo build.gradle de nivel de proyecto, asegúrate de incluir el repositorio Maven de Google en las secciones buildscript y allprojects.

  2. Crea un objeto de app de Firebase y pasa la actividad y el entorno de JNI:

    app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);

  3. Define una clase que implemente la interfaz firebase::messaging::Listener.

  4. Inicializa FCM y pasa la app y un objeto de escucha construido, de la siguiente manera:

    ::firebase::messaging::Initialize(app, listener);

  5. Las apps que usan el SDK de Servicios de Google Play deben verificar que el dispositivo tenga un APK de Servicios de Google Play compatible antes de acceder a las funciones. Para obtener más información, consulta Verifica el APK de los Servicios de Google Play.

iOS+

  1. Si aún no lo has hecho, agrega Firebase a tu proyecto de C++. Luego, configura tu proyecto para FCM de la siguiente manera:
    1. En el Podfile de tu proyecto, agrega la dependencia de FCM:
      pod 'FirebaseMessaging'
    2. Arrastra los frameworks firebase.framework y firebase_messaging.framework al proyecto de Xcode desde el SDK de C++ Firebase.
  2. Sube la clave de autenticación del APNS a Firebase. Si aún no tienes una, asegúrate de crearla en el Centro para miembros de Apple Developer.

    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 de APNS, en iOS app configuration, haz clic en el botón Subir.

    3. Busca la ubicación en la que guardaste la clave, selecciónala y haz clic en Abrir. Agrega el ID de clave correspondiente (disponible en el centro para miembros de Apple Developer) y haz clic en Subir.

  3. Configura tu proyecto Xcode a fin de habilitar las notificaciones push. Para ello, sigue estos pasos:

    1. Selecciona el proyecto en el área Navegador.
    2. Selecciona el destino del proyecto en el área Editor.
    3. Selecciona la pestaña General del área Editor.

      1. Desplázate a Bibliotecas y frameworks vinculados y haz clic en el botón + para agregar frameworks.
      2. En la ventana que se muestra, desplázate a UserNotifications.framework, haz clic en esa entrada y, luego, en Agregar.

        Este framework solo se muestra en Xcode 8 y versiones posteriores, y es obligatorio para usar esta biblioteca.

    4. Selecciona la pestaña Capacidades del área Editor.

      1. Activa Notificaciones push.
      2. Desplázate a Modos en segundo plano y activa esa opción.
      3. Selecciona Notificaciones remotas debajo de Modos en segundo plano.
  4. Crea un objeto de app de Firebase:

    app = ::firebase::App::Create(::firebase::AppOptions());

  5. Define una clase que implemente la interfaz firebase::messaging::Listener.

  6. Inicializa Firebase Cloud Messaging y pasa la app y un objeto de escucha construido, de la siguiente manera:

    ::firebase::messaging::Initialize(app, listener);

Accede al token de registro de dispositivo

Después de inicializar la biblioteca de Firebase Cloud Messaging, se solicita un token de registro para la instancia de app del cliente. La app recibirá el token con la devolución de llamada OnTokenReceived, que se debería definir en la clase que implementa firebase::messaging::Listener.

Si deseas orientar ese dispositivo específico, necesitarás acceder a este token.

Nota sobre la entrega de mensajes en Android

Cuando la app no se está ejecutando en absoluto y un usuario presiona una notificación, el mensaje no se envía, según la configuración predeterminada, a través de las devoluciones de llamada incorporadas en FCM. En este caso, las cargas útiles de los mensajes se reciben a través de un Intent que se usa para iniciar la aplicación. Para que FCM envíe estos mensajes entrantes a la devolución de llamada de la biblioteca de C++, debes anular el método onNewIntent en tu actividad y pasar el Intent al 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());
    // For older versions of Firebase C++ SDK (< 7.1.0), use `startService`.
    // startService(message);
    MessageForwardingService.enqueueWork(this, message);
  }
}

Los mensajes que se reciben mientras la app se ejecuta en segundo plano incluyen el contenido del campo de notificación que se usó para propagar la notificación de la bandeja del sistema. Sin embargo, no se comunicará el contenido de la notificación a FCM. Es decir, Message::notification tendrá un valor nulo.

Resumen:

Estado de la app Notificación Datos Ambos
Primer plano OnMessageReceived OnMessageReceived OnMessageReceived
Fondo Bandeja del sistema OnMessageReceived Notificación: Bandeja del sistema
Datos: En extras del intent.

Administración personalizada de mensajes en Android

Según la configuración predeterminada, las notificaciones enviadas a la app se pasan a ::firebase::messaging::Listener::OnMessageReceived, pero, en algunos casos, es posible que debas anular el comportamiento predeterminado. Para hacerlo en Android, deberás escribir clases personalizadas que extiendan com.google.firebase.messaging.cpp.ListenerService y también actualizar el archivo AndroidManifest.xml de tu proyecto.

Anular métodos ListenerService

El ListenerService es la clase Java que intercepta los mensajes entrantes enviados a la app y los dirige a la biblioteca de C++. Cuando la app se ejecuta en primer plano (o en segundo plano y recibe una carga útil solo de datos), los mensajes pasarán a través de una de las devoluciones de llamada proporcionadas en esta clase. Para agregar un comportamiento personalizado a la administración de mensajes, necesitarás extender el ListenerService predeterminado de FCM:

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

class MyListenerService extends ListenerService {

Puedes anular el método ListenerService.onMessageReceived para realizar acciones según el objeto RemoteMessage recibido y obtener los datos del mensaje:

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

El ListenerService tiene otros métodos que se utilizan con menos frecuencia y que también se pueden anular. Para obtener más detalles, consulta la información de referencia 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);
}

Actualizar AndroidManifest.xml

Una vez que se hayan escrito tus clases personalizadas, se deben incluir en el archivo AndroidManifest.xml para que surtan efecto. Asegúrate de que el manifiesto incluya las herramientas de combinación mediante la declaración del atributo apropiado en la etiqueta <manifest> de la siguiente manera:

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

En el archivo firebase_messaging_cpp.aar, se encuentra un archivo AndroidManifest.xml que declara el ListenerService predeterminado de FCM. Normalmente, este manifiesto se combina con el manifiesto específico del proyecto, de modo que se ejecute el ListenerService. Este ListenerService debe reemplazarse por el servicio de objeto de escucha personalizado. Para ello, quita el ListenerService predeterminado y agrega el servicio personalizado a través de las siguientes líneas en el archivo AndroidManifest.xml de tu proyecto:

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

Las versiones nuevas del SDK de Firebase C++ (7.1.0 y posteriores) usan JobIntentService, que requiere modificaciones adicionales en el archivo AndroidManifest.xml.

<service android:name="com.google.firebase.messaging.MessageForwardingService"
     android:permission="android.permission.BIND_JOB_SERVICE"
     android:exported="false" >
</service>

Evita la inicialización automática

FCM genera un token de registro para la segmentación por dispositivo. Cuando se genera un token, la biblioteca sube el identificador y los datos de configuración a Firebase. Si deseas obtener una habilitación explícita antes de usar el token, puedes evitar que se genere en el momento de la configuración inhabilitando FCM (y Analytics en Android). Para ello, agrega un valor de metadatos a Info.plist (no a GoogleService-Info.plist) en plataformas de Apple, o a AndroidManifest.xml en 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>

Swift

FirebaseMessagingAutoInitEnabled = NO

Para volver a habilitar FCM, realiza una llamada de tiempo de ejecución, de la siguiente manera:

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

Este valor persiste en todos los reinicios de la aplicación una vez establecido.

FCM permite enviar mensajes que contengan un vínculo directo a una app. Para recibir mensajes que contengan un vínculo directo, debes agregar un filtro de intents nuevo a la actividad que administra los vínculos directos para tu app. El filtro de intents debe capturar vínculos directos del dominio. Si los mensajes no contienen un vínculo directo, esta configuración no es necesaria. En 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>

También es posible especificar un comodín para aumentar la flexibilidad del filtro de intent. Por ejemplo:

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

Cuando los usuarios presionen una notificación con un vínculo al esquema y al host que especificaste, tu app iniciará la actividad con este filtro de intent para administrar el vínculo.

Próximos pasos

Después de configurar la app cliente, estás listo para enviar mensajes descendentes y a temas con Firebase. Para obtener más información, consulta la demostración que se incluye en la guía de inicio rápido de ejemplo que puedes descargar, ejecutar y revisar.

Para agregar otro comportamiento más avanzado a tu app, consulta las guías para enviar mensajes desde un servidor de apps.

Recuerda que necesitarás una implementación de servidor para usar estas funciones.