Начало работы с Firebase Cloud Messaging в приложениях C++

Выберите платформу: iOS+ Android Веб Flutter Unity C++


В этом руководстве рассказывается, как начать работу с Firebase Cloud Messaging в клиентских приложениях на C++, чтобы надежно отправлять сообщения.

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

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

Android

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

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

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

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

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

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

  4. Инициализируйте FCM, передав приложение и созданный объект 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 из Firebase C++ SDK в проект Xcode.
  2. Загрузите ключ аутентификации APNs в Firebase. Если у вас ещё нет ключа аутентификации APNs, создайте его в Центре разработчиков Apple.

    1. В консоли Firebase выберите Настройки > Общие. Затем нажмите на вкладку Обмен сообщениями в облаке.
    2. В разделе Конфигурация приложения для iOS в поле Ключ аутентификации APNs нажмите Загрузить, чтобы загрузить ключ аутентификации для разработки, ключ аутентификации для производства или оба ключа. Обязательно заполните как минимум одно из этих полей.
    3. Перейдите к месту, где сохранен ключ, выберите его и нажмите Открыть. Добавьте идентификатор ключа (его можно найти в Центре участников Apple Developer) и нажмите Загрузить.
  3. Настройте проект Xcode, чтобы включить push-уведомления:

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

      1. Прокрутите страницу до раздела Linked Frameworks and Libraries (Связанные фреймворки и библиотеки) и нажмите кнопку +, чтобы добавить фреймворки.
      2. В открывшемся окне прокрутите страницу до раздела UserNotifications.framework, нажмите на него и выберите Добавить.

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

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

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

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

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

  6. Инициализируйте Firebase Cloud Messaging, передав приложение и созданный объект Listener:

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

Как получить доступ к идентификатору установки Firebase

Как включить регистрацию с помощью идентификатора установки Firebase

Чтобы зарегистрировать экземпляр приложения в FCM с помощью идентификатора установки Firebase (FID), сначала включите FID в конфигурации приложения для платформ Android и Apple:

Android

Добавьте следующий элемент <meta-data> в элемент <application> файла AndroidManifest.xml:

<meta-data android:name="firebase_messaging_installation_id_enabled"
           android:value="true" />

Swift

Добавьте ключ FirebaseMessagingInstallationIdEnabled в файл Info.plist и задайте для него значение YES:

FirebaseMessagingInstallationIdEnabled = YES

Как реализовать прослушиватель onRegistrationReceived

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

class MyListener : public firebase::messaging::Listener {
 public:
  void OnRegistrationReceived(const char* installation_id) override {
    LogMessage("Received Firebase Installation ID: %s", installation_id);
    // TODO: Send the Firebase Installation ID (FID) to your app server to
    // target this device for messages.
  }
};

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

Как зарегистрироваться вручную, если автоинициализация отключена

Вы также можете вручную запустить регистрацию с помощью FCM во время выполнения, используя Register():

// Manually register with FCM
firebase::Future<void> register_future = firebase::messaging::Register();
register_future.OnCompletion([](const firebase::Future<void>& future) {
  if (future.status() == firebase::kFutureStatusComplete &&
      future.error() == 0) {
    // Note: The registered Firebase Installation ID is delivered to the
    // OnRegistrationReceived callback.
    LogMessage("Registered with FCM");
  }
});

Доступ к токену регистрации FCM (поддержка прекращена)

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

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

::firebase::messaging::SetRegistrationOnInitEnabled(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>

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

Дальнейшие действия

После того как вы выполните все шаги по настройке, вы можете продолжить работу с FCM для C++ одним из следующих способов: