Настройка клиентского приложения Firebase Cloud Messaging с помощью C++

Чтобы написать кроссплатформенное клиентское приложение Firebase Cloud Messaging на C++, используйте API Firebase Cloud Messaging . C++ SDK работает как на Android, так и на Apple, но для каждой платформы требуется дополнительная настройка.

Настройка Firebase и FCM SDK

Андроид

  1. Если вы еще этого не сделали, добавьте Firebase в свой проект C++ .

    • В инструкциях по настройке по ссылке ознакомьтесь с требованиями к устройству и приложению для использования Firebase C++ SDK, включая рекомендацию использовать CMake для сборки вашего приложения.

    • В файле build.gradle уровня проекта обязательно включите репозиторий Maven от Google в разделы buildscript и allprojects .

  2. Создайте объект Firebase App, передав среду JNI и Activity:

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

  3. Определите класс, реализующий интерфейс firebase::messaging::Listener .

  4. Инициализируем FCM , передавая App и сконструированный Listener:

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

  5. Приложения, использующие SDK сервисов Google Play, должны проверять наличие совместимого APK-файла сервисов Google Play на устройстве перед доступом к функциям. Подробнее см. в статье «Проверка наличия APK-файла сервисов Google Play» .

iOS+

  1. Если вы ещё этого не сделали, добавьте Firebase в свой проект C++ . Затем, чтобы настроить проект для FCM :
    1. В Podfile вашего проекта добавьте зависимость FCM:
      pod 'FirebaseMessaging'
    2. Перетащите фреймворки firebase.framework и firebase_messaging.framework в свой проект Xcode из Firebase C++ SDK .
  2. Загрузите свой ключ аутентификации APNs в Firebase. Если у вас ещё нет ключа аутентификации APNs, обязательно создайте его в Центре разработчиков Apple .

    1. Внутри вашего проекта в консоли Firebase выберите значок шестеренки, выберите Настройки проекта , а затем выберите вкладку Облачные сообщения .

    2. В разделе «Ключ аутентификации APNs» в настройках приложения iOS нажмите кнопку «Загрузить» .

    3. Перейдите к месту сохранения ключа, выберите его и нажмите «Открыть» . Добавьте идентификатор ключа (доступен в Центре разработчиков Apple ) и нажмите «Загрузить» .

  3. Настройте свой проект Xcode для включения Push-уведомлений:

    1. Выберите проект в области навигатора .
    2. Выберите целевой проект в области редактора .
    3. Выберите вкладку Общие в области Редактора .

      1. Прокрутите вниз до раздела Связанные фреймворки и библиотеки , затем нажмите кнопку + , чтобы добавить фреймворки.
      2. В появившемся окне прокрутите до UserNotifications.framework , щелкните по этой записи, затем щелкните Добавить .

        Этот фреймворк появляется только в Xcode v8 и более поздних версиях и требуется для этой библиотеки.

    4. Выберите вкладку Возможности в области Редактора .

      1. Включите функцию Push-уведомлений .
      2. Прокрутите вниз до раздела Фоновые режимы , затем переключите его в положение Вкл .
      3. В разделе «Фоновые режимы» выберите «Удаленные уведомления» .
  4. Создайте объект приложения Firebase:

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

  5. Определите класс, реализующий интерфейс firebase::messaging::Listener .

  6. Инициализируем Firebase Cloud Messaging, передав приложение и созданный прослушиватель:

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

Доступ к токену регистрации устройства

При инициализации библиотеки Firebase Cloud Messaging для экземпляра клиентского приложения запрашивается регистрационный токен. Приложение получит токен с помощью обратного вызова OnTokenReceived , который должен быть определен в классе, реализующем firebase::messaging::Listener .

Если вы хотите настроить таргетинг на это конкретное устройство, вам понадобится доступ к этому токену.

Примечание о доставке сообщений на Android

Когда приложение не запущено, а пользователь нажимает на уведомление, сообщение по умолчанию не перенаправляется через встроенные обратные вызовы FCM . В этом случае полезные данные сообщения принимаются через Intent , используемый для запуска приложения. Чтобы FCM перенаправлял эти входящие сообщения обратному вызову библиотеки C++, необходимо переопределить метод onNewIntent в Activity и передать Intent в 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);
  }
}

Сообщения, полученные во время работы приложения в фоновом режиме, содержат содержимое поля уведомления, используемое для заполнения уведомления в системном трее, но это содержимое не будет передано в FCM . То есть, Message::notification будет иметь значение null.

В итоге:

Состояние приложения Уведомление Данные Оба
Передний план OnMessageReceived OnMessageReceived OnMessageReceived
Фон Системный лоток OnMessageReceived Уведомление: системный трей
Данные: в дополнениях к намерению.

Пользовательская обработка сообщений на Android

По умолчанию уведомления, отправляемые в приложение, передаются в ::firebase::messaging::Listener::OnMessageReceived , но в некоторых случаях может потребоваться переопределить поведение по умолчанию. Для этого на Android потребуется написать собственные классы, расширяющие com.google.firebase.messaging.cpp.ListenerService , а также обновить AndroidManifest.xml вашего проекта.

Переопределить методы ListenerService .

ListenerService — это класс Java, который перехватывает входящие сообщения, отправляемые приложению, и перенаправляет их в библиотеку C++. Когда приложение находится на переднем плане (или в фоновом режиме и получает полезную нагрузку, содержащую только данные), сообщения проходят через один из обратных вызовов, предоставляемых этим классом. Чтобы добавить пользовательское поведение к обработке сообщений, необходимо расширить стандартный ListenerService FCM :

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

class MyListenerService extends ListenerService {

Переопределив метод ListenerService.onMessageReceived , вы можете выполнять действия на основе полученного объекта RemoteMessage и получать данные сообщения:

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

У ListenerService также есть несколько других методов, которые используются реже. Их также можно переопределить. Подробнее см. в справочнике по 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);
}

Обновить AndroidManifest.xml

После написания пользовательских классов их необходимо включить в файл AndroidManifest.xml , чтобы они вступили в силу. Убедитесь, что манифест включает инструменты слияния, объявив соответствующий атрибут внутри тега <manifest> , например:

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

В архиве firebase_messaging_cpp.aar находится файл AndroidManifest.xml , в котором объявлена ListenerService по умолчанию для FCM . Этот манифест обычно объединяется с манифестом проекта, что и обеспечивает работу службы ListenerService . Эту ListenerService необходимо заменить на пользовательскую службу ListenerService. Это достигается удалением ListenerService по умолчанию и добавлением пользовательской службы. Это можно сделать, добавив следующие строки в файл AndroidManifest.xml вашего проекта:

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

Новые версии Firebase C++ SDK (начиная с 7.1.0) используют JobIntentService , что требует дополнительных изменений в файле AndroidManifest.xml .

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

Запретить автоматическую инициализацию

FCM генерирует регистрационный токен для таргетинга устройств. При генерации токена библиотека загружает идентификатор и данные конфигурации в Firebase. Если вы хотите получить явное согласие перед использованием токена, вы можете запретить генерацию во время настройки, отключив FCM (а на Android — Analytics). Для этого добавьте значение метаданных в файл Info.plist (а не GoogleService-Info.plist ) на платформах Apple или в файл AndroidManifest.xml на 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>

Быстрый

FirebaseMessagingAutoInitEnabled = NO

Чтобы повторно включить FCM, можно выполнить вызов во время выполнения:

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

После установки это значение сохраняется при перезапуске приложения.

FCM позволяет отправлять сообщения, содержащие глубокую ссылку на ваше приложение. Чтобы получать сообщения, содержащие глубокую ссылку, необходимо добавить новый фильтр намерений в Activity, обрабатывающий глубокие ссылки для вашего приложения. Фильтр намерений должен отлавливать глубокие ссылки вашего домена. Если ваши сообщения не содержат глубокую ссылку, эта настройка не требуется. В 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>

Также можно указать подстановочный знак, чтобы сделать фильтр намерений более гибким. Например:

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

Когда пользователи нажимают на уведомление, содержащее ссылку на указанную вами схему и хост, ваше приложение начинает действие с этим фильтром намерений для обработки ссылки.

Следующие шаги

После настройки клиентского приложения вы готовы к отправке сообщений по нисходящей линии и темам с помощью Firebase. Чтобы узнать больше, ознакомьтесь с демонстрацией этой функции в примере быстрого старта , который вы можете скачать, запустить и изучить.

Чтобы добавить в свое приложение другое, более продвинутое поведение, ознакомьтесь с руководствами по отправке сообщений с сервера приложений:

Имейте в виду, что для использования этих функций вам понадобится реализация сервера .