Вы когда-нибудь задумывались, как смартфоны получают и обрабатывают уведомления приложений в разных состояниях: открыто/закрыто/в фоновом режиме?
Firebase Cloud Messaging — это кроссплатформенный инструмент для отправки push-уведомлений на одно или несколько устройств. Мгновенные сообщения могут передать полезную нагрузку в приложение клиента размером до 4 кб.
Теперь давайте применим FCM в проекте, запущенном в Android Studio.
Создание проекта Firebase
Откройте консоль Firebase, нажмите Add Project и следуйте шагам для настройки проекта (также можете воспользоваться этой инструкцией “Добавьте Firebase в свой проект Android”).
Затем добавьте приложение в созданный проект.
Введите название проекта, название пакета и ключ SHA-1 от проекта в Android Studio. Следуйте инструкции, чтобы завершить подключение приложения к Firebase.
Готово. Вы подключили Firebase к проекту Android. Теперь добавим Firebase SDK в проект для работы с FCM.
Добавление Firebase SDK
Шаг 1: добавьте код ниже в файл <project>/build.gradle:
buildscript {
dependencies {
// Добавьте строку
classpath 'com.google.gms:google-services:4.3.2'
}
}
Шаг 2: добавьте код ниже в <project>/<app>/build.gradle:
dependencies {
// Добавьте строку
implementation 'com.google.firebase:firebase-messaging:20.0.0'
}
...
// Добавьте в конец этого файла
apply plugin: 'com.google.gms.google-services'
Шаг 3: нажмите Sync Now для синхронизации изменений в gradle.
Отправка сообщений
- На одно устройство: для этого нужен регистрационный токен приложения клиента, который генерируется при помощи Firebase SDK. Имейте в виду, что этот токен динамический и будет регулярно меняться.
Получить текущий токен можно так:
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed",
task.getException());
return;
}
// Новый ID токена
String token = task.getResult().getToken();
}
});
2. На несколько устройств: для этого все устройства должны подписаться на общую тему “xyz”.
Вставьте следующий код в Activity, чтобы подписаться или отписаться:
Subscribe Topic :
FirebaseMessaging.getInstance().subscribeToTopic("TopicName");
Unsubscribe Topic : FirebaseMessaging.getInstance().unsubscribeFromTopic("TopicName");
Типы сообщений Firebase
- Уведомления: такие сообщения нельзя кастомизировать. У них есть только два ключевых значения:
title
иbody
.
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
2. Данные: сообщения с данными обрабатываются приложением Android. Они подходят для отправки сообщений, включающих данные. Их можно кастомизировать в паре ключ-значение:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
3. Гибрид из двух вышеуказанных: сообщение может содержать уведомления с данными. Такие сообщения обрабатываются двумя сценариями в зависимости от состояния приложения (работа в фоновом режиме/открыто). Используем ключи уведомлений и данных:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
}
Обработка сообщений Firebase
Как сказано выше, сообщения FCM будут обрабатываться по-разному в зависимости от типа полезной нагрузки и состояния приложения.
Обработка уведомлений:
Если приложение работает в фоновом режиме, система сама автоматически обрабатывает уведомление и выводит его на экран без открытия приложения.
Если приложение открыто, то необходимо вызвать функцию onMessageReceived
. Для этого создайте класс Java MyFirebaseMessagingService
, расширяющий FirebaseMessagingService
.
Объявите действие в качестве службы в App Manifest:
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Напишите следующий код в MyFirebaseMessagingService
для функции onMessageReceived
:
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
sendNotification(remoteMessage);
}
private void sendNotification(RemoteMessage remoteMessage) {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =PendingIntent.getActivity(this,
m,intent,PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder;
notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.geekhaven_transparent)
.setContentTitle(remoteMessage.getNotification.getTitle)
.setContentText(remoteMessage.getNotification.getBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Необходим канал уведомлений Android Oreo
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(m, notificationBuilder.build());
Для отправки уведомлений с полезной нагрузкой измените две следующие строки:
вместо:
.setContentTitle(remoteMessage.getNotification.getTitle)
.setContentText(remoteMessage.getNotification.getBody)
пишем:
.setContentTitle(remoteMessage.getData.get("your_key1")
.setContentText(remoteMessage.getData.get("your_key2")
Если вы отправляете уведомления с бэкенда, то необходимо отправлять регистрационный токен каждый раз, когда он меняется. Для этого посмотрите на метод onNewToken
в MyMessagingService.
Как выбрать полезную нагрузку?
Выбор зависит от вашей цели. Например, если нужно отправить в уведомлении только заголовок и тело, то выбираем уведомления. Если нужно отправить больше информации или кастомизировать уведомление, добавив действия, то выбираем отправку данных. Такие уведомления всегда попадают в метод onMessageReceived
независимо от того, в каком состоянии находится приложение.
Кастомизировать уведомления можно только в том случае, если приложение открыто. Если приложение работает в фоновом режиме или отключено, то уведомления обрабатываются системой.
Как отправить FCM сообщение вручную?
Отправлять уведомления можно из консоли Firebase: Firebase Console — →Grow — →Cloud Messaging:
Нажмите на Send your first message, заполните заголовок и тело.
Если хотите отправить уведомление на определенное устройство, нажмите на Send test message и введите текущий регистрационный токен.
Нажмите Test.
Если хотите отправить уведомление, используя тему, нажмите на next, выберите текущее приложение и введите тему.
Нажмите на Publish.
А вот и уведомление:
Отправить данные или гибрид вручную через Firebase нельзя, так как для этого еще нет инструмента, но для этих случаев можно скачать или добавить расширение POSTMAN.
Отправка данных по протоколу HTTP с помощью POSTMAN
Шаг 1. Выберите POST. Введите запрос URL: https://fcm.googleapis.com/fcm/send
Шаг 2. Добавьте заголовки Authorization: key=<server_key>
и Content-Type: application/json
.
Как получить Server_key?
Откройте консоль Firebase — →Project Settings — →Cloud Messaging.
Для отправки сообщения выберите Body — →Raw — →JSON(application/json).
{
"to" : "YOUR_FCM_TOKEN",
"data" : {
"body" : "Notification Body",
"title": "Notification Title",
"key_1" : "Value for key_1",
"key_2" : "Value for key_2"
}
}
С помощью POSTMAN можно отправлять и уведомления. Для всех трех типов используйте следующий код:
{
"to" : "YOUR_FCM_TOKEN",
"notification" : {
"body" : "Body of Your Notification",
"title": "Title of Your Notification"
},
"data" : {
"body" : "Notification Body",
"title": "Notification Title",
"key_1" : "Value for key_1",
"key_2" : "Value for key_2"
}
}
Чтобы отправить уведомление на несколько устройств используйте registration_ids
или "to":"topic/topic_name"
вместо to
.
Читайте также:
- Навигация по настраиваемой доставке
- Как создать масштабируемую архитектуру для крупных мобильных проектов
- Сортировка и фильтрация записей с помощью базы данных Room и Kotlin Flow
Читайте нас в Telegram, VK и Дзен
Перевод статьи VARUN BHARDWAJ: Sending Push Notifications by Using Firebase Cloud Messaging