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

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

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

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

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

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

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

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

В итоге:

Состояние приложения Уведомление Данные Оба
Передний план 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 направляет уведомления в системный трей. При нажатии на уведомление по умолчанию открывается панель запуска приложений.

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

Для получения более подробной информации о доставке сообщений в ваше приложение см. панель отчетности 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 также должно поддерживать прямую загрузку (без доступа к защищенному хранилищу учетных данных в режиме прямой загрузки).

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