Настройка клиентского приложения Firebase Cloud Messaging на Android

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

Настройте SDK

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

Отредактируйте манифест вашего приложения

Добавьте в манифест вашего приложения следующее:

  • Служба, расширяющая FirebaseMessagingService . Это необходимо, если вы хотите выполнять какую-либо обработку сообщений, помимо получения уведомлений о приложениях в фоновом режиме. Чтобы получать уведомления в приложениях на переднем плане, получать полезные данные, отправлять восходящие сообщения и т. д., вам необходимо расширить эту службу.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (Необязательно) В компоненте приложения элементы метаданных для установки значка и цвета уведомления по умолчанию. Android использует эти значения всякий раз, когда для входящих сообщений явно не задан значок или цвет.
  • <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
         See README(https://goo.gl/l4GJaQ) for more. -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_stat_ic_notification" />
    <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
         notification message. See README(https://goo.gl/6BKBk7) for more. -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />
  • (Необязательно) Начиная с Android 8.0 (уровень API 26) и выше поддерживаются и рекомендуются каналы уведомлений . FCM предоставляет канал уведомлений по умолчанию с базовыми настройками. Если вы предпочитаете создавать и использовать свой собственный канал по умолчанию, установите default_notification_channel_id в идентификатор вашего объекта канала уведомлений, как показано; FCM будет использовать это значение всякий раз, когда для входящих сообщений явно не указан канал уведомления. Дополнительные сведения см. в разделе Управление каналами уведомлений .
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

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

В Android 13 представлено новое разрешение во время выполнения для отображения уведомлений. Это затронет все приложения, работающие на Android 13 или выше, которые используют уведомления FCM.

По умолчанию FCM SDK (версия 23.0.6 или выше) включает разрешение POST_NOTIFICATIONS , определенное в манифесте. Однако вашему приложению также потребуется запросить версию этого разрешения во время выполнения через константу android.permission.POST_NOTIFICATIONS . Вашему приложению не будет разрешено показывать уведомления, пока пользователь не предоставит это разрешение.

Чтобы запросить новое разрешение среды выполнения:

Kotlin+KTX

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

private fun askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

private void askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}

Как правило, вам следует отображать пользовательский интерфейс, объясняющий пользователю функции, которые будут включены, если он предоставит приложению разрешения на публикацию уведомлений. Этот пользовательский интерфейс должен предоставлять пользователю возможность согласиться или отклонить предложение, например кнопки «ОК» и «Нет, спасибо» . Если пользователь выбирает ОК , запросите разрешение напрямую. Если пользователь выберет Нет, спасибо , разрешите пользователю продолжить работу без уведомлений.

Дополнительные рекомендации о том, когда ваше приложение должно запрашивать разрешение POST_NOTIFICATIONS у пользователя , см. в разделе Разрешение выполнения уведомлений.

Разрешения на уведомления для приложений, ориентированных на Android 12L (уровень API 32) или ниже.

Android автоматически запрашивает у пользователя разрешение при первом создании вашего приложения канала уведомлений, пока приложение находится на переднем плане. Однако есть важные предостережения относительно сроков создания канала и запросов на разрешение:

  • Если ваше приложение создает свой первый канал уведомлений, когда оно работает в фоновом режиме (что делает FCM SDK при получении уведомления FCM), Android не позволит отображать уведомление и не будет запрашивать у пользователя разрешение на уведомление до следующего время открытия вашего приложения. Это означает, что все уведомления, полученные до того, как ваше приложение будет открыто и пользователь примет разрешение, будут потеряны .
  • Мы настоятельно рекомендуем вам обновить свое приложение до Android 13+, чтобы использовать API платформы для запроса разрешения. Если это невозможно, ваше приложение должно создать каналы уведомлений, прежде чем отправлять какие-либо уведомления в приложение, чтобы вызвать диалоговое окно разрешения на уведомления и гарантировать, что уведомления не будут потеряны. Дополнительные сведения см. в разделе «Рекомендации по разрешению уведомлений» .

Необязательно: удалите разрешение POST_NOTIFICATIONS .

По умолчанию FCM SDK включает разрешение POST_NOTIFICATIONS . Если ваше приложение не использует сообщения уведомлений (будь то через уведомления FCM, через другой SDK или непосредственно опубликованное вашим приложением) и вы не хотите, чтобы ваше приложение включало разрешение, вы можете удалить его с помощью маркера remove слияния манифеста . Имейте в виду, что удаление этого разрешения предотвращает отображение всех уведомлений, а не только уведомлений FCM. Добавьте следующее в файл манифеста вашего приложения:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

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

При первом запуске вашего приложения пакет SDK FCM создает токен регистрации для экземпляра клиентского приложения. Если вы хотите настроить таргетинг на отдельные устройства или создать группы устройств, вам потребуется доступ к этому токену, расширив FirebaseMessagingService и переопределив onNewToken .

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

Регистрационный токен может измениться в следующих случаях:

  • Приложение восстанавливается на новом устройстве.
  • Пользователь удаляет/переустанавливает приложение.
  • Пользователь удаляет данные приложения.

Получить текущий регистрационный токен

Когда вам нужно получить текущий токен, вызовите FirebaseMessaging.getInstance().getToken() :

Kotlin+KTX

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

Мониторинг генерации токенов

Обратный вызов onNewToken срабатывает всякий раз, когда генерируется новый токен.

Kotlin+KTX

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration token is initially generated so this is where you would retrieve the token.
 */
override fun onNewToken(token: String) {
    Log.d(TAG, "Refreshed token: $token")

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    Log.d(TAG, "Refreshed token: " + token);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

После получения токена вы можете отправить его на сервер приложений и сохранить его предпочтительным способом.

Проверьте наличие сервисов Google Play

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

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

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

Когда создается регистрационный токен FCM, библиотека загружает идентификатор и данные конфигурации в Firebase. Если вы предпочитаете запретить автоматическое создание токенов, отключите сбор аналитики и автоматическую инициализацию 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, выполните вызов во время выполнения:

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

Чтобы повторно включить сбор аналитики, вызовите метод setAnalyticsCollectionEnabled() класса FirebaseAnalytics . Например:

setAnalyticsCollectionEnabled(true);

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

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

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

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

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