Получайте сообщения в приложении для Android

Уведомления Firebase ведут себя по-разному в зависимости от состояния переднего плана/фона принимающего приложения. Если вы хотите, чтобы передние приложения получали уведомления или сообщения с данными, вам нужно написать код для обработки обратного вызова onMessageReceived . Для объяснения разницы между уведомлениями и сообщениями с данными см. Типы сообщений .

Обработка сообщений

Для получения сообщений используйте службу, расширяющую FirebaseMessagingService . Ваша служба должна переопределять обратные вызовы onMessageReceived и onDeletedMessages .

Временной интервал для обработки сообщения может быть короче 20 секунд в зависимости от задержек, возникших до вызова onMessageReceived , включая задержки ОС, время запуска приложения, блокировку основного потока другими операциями или слишком длительные предыдущие вызовы onMessageReceived . После этого времени различные поведения ОС, такие как завершение процесса Android или ограничения фонового выполнения Android O, могут помешать вам завершить работу.

onMessageReceived предоставляется для большинства типов сообщений, за исключением следующих:

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

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

В итоге:

Состояние приложения Уведомление Данные Оба
Передний план onMessageReceived onMessageReceived onMessageReceived
Фон Системный лоток onMessageReceived Уведомление: системный трей
Данные: в дополнениях к намерению.
Дополнительную информацию о типах сообщений см. в разделе Уведомления и сообщения с данными .

Редактировать манифест приложения

Чтобы использовать FirebaseMessagingService , вам необходимо добавить в манифест приложения следующее:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

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

Добавьте эти строки в тег application , чтобы задать пользовательский значок по умолчанию и пользовательский цвет:

<!-- 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 отображает пользовательский значок по умолчанию для

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

Android использует пользовательский цвет по умолчанию для

  • Все уведомления, отправленные из редактора уведомлений .
  • Любое сообщение уведомления, в котором явно не указан цвет в полезной нагрузке уведомления.

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

Переопределить onMessageReceived

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

Kotlin

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        // Check if data needs to be processed by long running job
        if (needsToBeScheduled()) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Переопределить onDeletedMessages

В некоторых ситуациях FCM может не доставить сообщение. Это происходит, когда на определенном устройстве слишком много сообщений (>100), ожидающих отправки для вашего приложения, на момент его подключения или если устройство не подключалось к FCM более месяца. В этих случаях вы можете получить обратный вызов FirebaseMessagingService.onDeletedMessages() Когда экземпляр приложения получает этот обратный вызов, он должен выполнить полную синхронизацию с вашим сервером приложений. Если вы не отправляли сообщение приложению на этом устройстве в течение последних 4 недель, FCM не вызовет onDeletedMessages() .

Обработка уведомлений в фоновом приложении

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

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

Для получения более подробной информации о доставке сообщений в ваше приложение см. панель отчетов FCM , которая регистрирует количество отправленных и открытых сообщений на устройствах Apple и Android, а также данные о «показах» (уведомлениях, просмотренных пользователями) для приложений Android.

Получать сообщения FCM в режиме прямой загрузки

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

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

Предпосылки

  • Устройство должно быть настроено для режима прямой загрузки.
  • На устройстве должна быть установлена ​​последняя версия сервисов Google Play (19.0.54 или более поздняя).
  • Для получения сообщений FCM приложение должно использовать FCM SDK ( com.google.firebase:firebase-messaging ).

Включите обработку сообщений режима прямой загрузки в вашем приложении

  1. В файле Gradle уровня приложения добавьте зависимость от библиотеки поддержки прямой загрузки FCM:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. Сделайте так, чтобы FirebaseMessagingService приложения поддерживал прямую загрузку, добавив атрибут android:directBootAware="true" в манифест приложения:

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

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

  • Служба не должна получать доступ к защищенному хранилищу учетных данных при работе в режиме прямой загрузки.
  • Служба не должна пытаться использовать компоненты, такие как Activities , BroadcastReceivers или другие Services , которые не помечены как поддерживающие прямую загрузку, при работе в режиме прямой загрузки.
  • Любые библиотеки, которые использует служба, также не должны получать доступ к защищенному хранилищу учетных данных или вызывать компоненты, не являющиеся компонентами directBootAware, во время работы в режиме прямой загрузки. Это означает, что любые библиотеки, которые использует приложение и которые вызываются из службы, должны быть либо осведомлены о прямой загрузке, либо приложение должно будет проверять, работает ли оно в режиме прямой загрузки, и не вызывать их в этом режиме. Например, Firebase SDK работают с прямой загрузкой (их можно включить в приложение, не вызывая сбоя в режиме прямой загрузки), но многие Firebase API не поддерживают вызов в режиме прямой загрузки.
  • Если приложение использует пользовательское Application , Application также должно поддерживать прямую загрузку (без доступа к защищенному хранилищу учетных данных в режиме прямой загрузки).

Инструкции по отправке сообщений на устройства в режиме прямой загрузки см. в разделе Отправка сообщений с включенной прямой загрузкой .