Уведомления 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+KTX
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
).
Включите обработку сообщений режима прямой загрузки в вашем приложении.
В файле Gradle уровня приложения добавьте зависимость от библиотеки поддержки прямой загрузки FCM:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
Обеспечьте поддержку прямой загрузки приложения
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, во время работы в режиме прямой загрузки. Это означает, что любые библиотеки, которые использует приложение и которые вызываются из службы, либо должны быть осведомлены о прямой загрузке, либо приложению необходимо будет проверять, работает ли оно в режиме прямой загрузки, а не вызывать их в этом режиме. Например, SDK Firebase работают с прямой загрузкой (их можно включить в приложение без сбоя в режиме прямой загрузки), но многие API Firebase не поддерживают вызов в режиме прямой загрузки.
- Если приложение использует пользовательское
Application
,Application
также должно поддерживать прямую загрузку (нет доступа к хранилищу, защищенному учетными данными, в режиме прямой загрузки).
Инструкции по отправке сообщений на устройства в режиме прямой загрузки см. в разделе Отправка сообщений с поддержкой прямой загрузки .