Как начать работу с Firebase Cloud Messaging в приложениях Flutter

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


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

В зависимости от платформы, на которую вы настраиваете таргетинг, вам нужно будет выполнить дополнительные действия.

iOS+

Подмена методов

Чтобы использовать плагин Flutter FCM на устройствах Apple, необходимо переопределение методов. Без него ключевые функции Firebase, такие как обработка регистрации FCM, не будут работать должным образом.

Android

Сервисы Google Play

Для клиентов FCM требуются устройства с Android 7.0 или более поздней версии и установленными сервисами Google Play или эмулятор с Android 7.0 и API Google. Обратите внимание, что вы не ограничены в развертывании приложений Android через Google Play.

Приложения, использующие Play Services SDK, должны всегда проверять, есть ли на устройстве совместимый APK-файл сервисов Google Play, прежде чем обращаться к функциям сервисов Google Play. Рекомендуется сделать это в двух местах: в методе onCreate() основного класса activity и в его методе onResume(). Проверка в onCreate() гарантирует, что приложение нельзя будет использовать, если она не будет пройдена. Проверка в методе onResume() гарантирует, что если пользователь вернется в запущенное приложение другим способом, например с помощью кнопки "Назад", проверка все равно будет выполнена.

Если на устройстве нет совместимой версии сервисов Google Play, ваше приложение может вызвать метод GoogleApiAvailability.makeGooglePlayServicesAvailable(), чтобы пользователи могли скачать сервисы Google Play из Google Play.

Веб-приложение

Как настроить учетные данные для сайта с помощью FCM

Веб-интерфейс FCM использует веб-учетные данные, называемые ключами добровольной идентификации сервера приложений (VAPID), для авторизации запросов на отправку в поддерживаемые сервисы веб-push-уведомлений. Чтобы подписать приложение на push-уведомления, необходимо связать пару ключей с проектом Firebase. Вы можете сгенерировать новую пару ключей или импортировать существующую через консоль Firebase.

Установите плагин FCM

  1. Если вы ещё этого не сделали, установите и инициализируйте плагины Firebase для Flutter.

  2. Чтобы установить плагин, в корневом каталоге проекта Flutter выполните следующую команду:

    flutter pub add firebase_messaging
    
  3. После этого пересоберите приложение Flutter:

    flutter run
    

Запросить разрешение на уведомления

Чтобы отправить уведомление на устройство, зарегистрируйте его в FCM с помощью register(). Если разрешение на уведомления не предоставлено, этот метод запросит его у пользователя. В противном случае он передает FID через onRegistered в случае успеха или отклоняет будущий запрос из-за ошибки.

// You may set the permission requests to "provisional" which allows the user to choose what type
// of notifications they would like to receive once the user receives a notification.
final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);

// For apple platforms, make sure the APNS token is available before making any FCM plugin API calls
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
 // APNS token is available, make FCM plugin API requests...
}

Как получить доступ к идентификатору установки 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" />

iOS+

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

<key>FirebaseMessagingInstallationIdEnabled</key>
<true/>

Подписаться на ленту onRegistered

Чтобы отправить сообщение экземпляру приложения на определенном устройстве, вам понадобится идентификатор установки Firebase (FID) этого экземпляра приложения, зарегистрированного в FCM. FID передается асинхронно через поток onRegistered.

На платформах Android и Apple FCM автоматически регистрирует экземпляр приложения при запуске, если включена автоинициализация (по умолчанию). Однако необходимо явно вызвать функцию register():

  • На веб-страницах. Также можно передать объекты vapidKey и serviceWorkerScriptPath.
  • На платформах Android и Apple, если автоматическая инициализация отключена или после вызова unregister(). Вы также можете в любое время позвонить на номер register(), чтобы активировать onRegistered с уже зарегистрированным идентификатором FID.

Всегда подписывайтесь на onRegistered перед вызовом register(), чтобы прослушиватель был активен при создании события регистрации.

final messaging = FirebaseMessaging.instance;

messaging.onRegistered
    .listen((String installationId) {
      // TODO: Send the Firebase Installation ID (FID) to your application server.
    })
    .onError((err) {
      // Error getting Firebase Installation ID.
    });

// Required on Web, and on Android/Apple if auto-initialization is disabled.
await messaging.register(
  // Optional on Web (ignored on Android and Apple platforms)
  vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu",
);

Поток onRegistered передает идентификатор FID в следующих случаях:

  1. Автоматически при первом запуске приложения и обычной синхронизации на платформах Android и Apple, если включена автоматическая инициализация.
  2. Каждый раз, когда завершается вызов register(), выполненный вручную (даже если экземпляр приложения уже зарегистрирован, onRegistered по-прежнему выдает уже зарегистрированный FID).
  3. При обнаружении изменения идентификатора установки Firebase и повторной регистрации приложения в FCM или при запуске события pushsubscriptionchange на сайте.

Получив идентификатор установки Firebase (FID), отправьте его на сервер приложения и сохраните удобным для вас способом.

Как получить токен регистрации (поддержка прекращена)

Чтобы отправить сообщение на определенное устройство, вам понадобится токен регистрации устройства. Чтобы получить токен регистрации для экземпляра приложения, вызовите метод getToken(). Если разрешение на уведомления не предоставлено, этот метод запросит его у пользователя. В противном случае возвращается токен или отклоняется будущий запрос из-за ошибки.

На веб-платформах передайте открытый ключ VAPID в getToken():

final fcmToken = await FirebaseMessaging.instance.getToken(vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu");

Чтобы получать уведомления об обновлении токена, подпишитесь на поток onTokenRefresh:

FirebaseMessaging.instance.onTokenRefresh
    .listen((fcmToken) {
      // TODO: If necessary send token to application server.

      // Note: This callback is fired at each app startup and whenever a new
      // token is generated.
    })
    .onError((err) {
      // Error getting token.
    });

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

Когда создается регистрация FCM, библиотека загружает идентификатор и данные конфигурации в Firebase. Если вы хотите предотвратить автоматическую регистрацию, отключите автоматическую инициализацию во время сборки.

Если автоматическая инициализация отключена, вы можете явно зарегистрировать экземпляр приложения во время выполнения, вызвав register() (сначала подпишитесь на onRegistered, чтобы получить идентификатор установки Firebase):

await FirebaseMessaging.instance.register();

iOS

Если вы используете iOS, добавьте значение метаданных в Info.plist:

FirebaseMessagingAutoInitEnabled = NO

Android

На устройствах Android отключите сбор данных Аналитики и автоматическую инициализацию FCM (необходимо отключить оба параметра), добавив следующие значения метаданных в файл AndroidManifest.xml:

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

Как повторно включить автоматическую инициализацию FCM во время выполнения

Чтобы включить автоматическую инициализацию для определенного экземпляра приложения, вызовите setAutoInitEnabled():

await FirebaseMessaging.instance.setAutoInitEnabled(true);

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

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

  1. Установите и запустите приложение на целевом устройстве. На устройствах Apple вам нужно будет принять запрос на разрешение получать удаленные уведомления.

  2. Убедитесь, что приложение работает в фоновом режиме.

  3. В консоли Firebase выберите DevOps & Engagement (DevOps и взаимодействие) > Messaging (Обмен сообщениями).

  4. Создайте кампанию.

    • Если это ваше первое сообщение:

      1. Выберите Создать первую кампанию.

      2. Выберите Уведомления Firebase и нажмите Создать.

    • Если у вас уже есть кампании:

      1. На вкладке Кампании выберите Новая кампания.

      2. Нажмите Уведомления.

  5. Введите текст сообщения.

  6. На панели справа выберите Отправить тестовое сообщение.

  7. В поле Добавьте идентификатор установки Firebase или FCM токен регистрации введите зарегистрированный идентификатор установки Firebase или токен регистрации.

  8. Нажмите Проверить.

После нажатия кнопки Тестировать целевое клиентское устройство, на котором приложение работает в фоновом режиме, должно получить уведомление.

Чтобы узнать, как сообщения доставляются в ваше приложение, откройте раздел DevOps и вовлеченность > Обмен сообщениями > Отчеты на панели управления Firebase. На этой панели управления регистрируется количество сообщений, отправленных и открытых на устройствах Apple и Android, а также данные о показах (уведомлениях, которые видели пользователи) для приложений Android.

Обработка взаимодействия

Когда пользователь нажимает на уведомление, режим работы по умолчанию на Android и iOS — открывать приложение. Если приложение закрыто, оно будет запущено, а если оно работает в фоновом режиме, то будет переведено в активный режим.

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

Пакет firebase-messaging предлагает два способа обработки этого взаимодействия:

  1. getInitialMessage(): Если приложение открывается из закрытого состояния, этот метод возвращает Future, содержащий RemoteMessage. После использования RemoteMessage будет удален.
  2. onMessageOpenedApp – Stream, который публикует RemoteMessage, когда приложение открывается из фонового режима.

Чтобы у пользователей не возникало проблем, вам следует предусмотреть оба варианта. В примере кода ниже показано, как это сделать.

class Application extends StatefulWidget {
  @override
  State createState() => _Application();
}

class _Application extends State {
  // In this example, suppose that all messages contain a data field with the key 'type'.
  Future setupInteractedMessage() async {
    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage != null) {
      _handleMessage(initialMessage);
    }

    // Also handle any interaction when the app is in the background using a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

  void _handleMessage(RemoteMessage message) {
    if (message.data['type'] == 'chat') {
      Navigator.pushNamed(context, '/chat',
        arguments: ChatArguments(message),
      );
    }
  }

  @override
  void initState() {
    super.initState();

    // Run code required to handle interacted messages in an async function
    // as initState() must not be async
    setupInteractedMessage();
  }

  @override
  Widget build(BuildContext context) {
    return Text("...");
  }
}

Способ взаимодействия зависит от ваших настроек. Приведенный выше пример – это базовый пример использования StatefulWidget.

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

После завершения настройки вы можете выполнить следующие действия с FCM для Flutter: