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