Как получать сообщения в приложениях Android

Выберите платформу: iOS+ Android Веб Flutter Unity C++


Чтобы получать сообщения, можно использовать сервис, который расширяет возможности FirebaseMessagingService. Ваш сервис должен переопределять функции обратного вызова onMessageReceived и onDeletedMessages. Полный пример можно найти в кратком руководстве по Firebase Cloud Messaging.

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

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

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

В целом можно выделить следующее.

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

Подробнее об уведомлениях и сообщениях с данными…

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

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

Измените манифест приложения

Чтобы использовать 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 показывает значок приложения, отрисованный белым цветом.

Переопределить 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(). Когда экземпляр приложения получает этот обратный вызов, он должен выполнить полную синхронизацию с сервером приложения. Если вы не отправляли сообщения в приложение на этом устройстве в течение последних четырех недель, FCM не будет вызывать onDeletedMessages().

Как обрабатывать уведомления в фоновом приложении

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

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

Чтобы узнать, как сообщения доставляются в ваше приложение, перейдите в раздел DevOps & Engagement (DevOps и вовлечение) > Messaging (Обмен сообщениями) > Reports (Отчеты) в консоли Firebase. На этой панели управления регистрируется количество сообщений, отправленных и открытых на устройствах Apple и Android, а также данные о показах (уведомлениях, которые видели пользователи) для приложений Android.