Уведомления Firebase ведут себя по-разному в зависимости от активного/фонового состояния принимающего приложения. Если вы хотите, чтобы приоритетные приложения получали уведомления или сообщения с данными, вам потребуется написать код для обработки обратного вызова onMessageReceived
. Объяснение разницы между уведомлениями и сообщениями данных см. в разделе Типы сообщений .
Обработка сообщений
Для получения сообщений используйте службу, которая расширяет FirebaseMessagingService . Ваша служба должна переопределять обратные вызовы onMessageReceived
и onDeletedMessages
. Он должен обрабатывать любое сообщение в течение 20 секунд после получения (10 секунд на Android Marshmallow). Временное окно может быть короче в зависимости от задержек операционной системы перед вызовом onMessageReceived
. По истечении этого времени различные варианты поведения ОС, такие как ограничения фонового выполнения 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
также должно быть осведомлено о прямой загрузке (без доступа к защищенному хранилищу учетных данных в режиме прямой загрузки).
Инструкции по отправке сообщений на устройства в режиме прямой загрузки см. в разделе Отправка сообщений с включенной прямой загрузкой .