Удаленные уведомления с помощью Firebase Cloud Messaging
В этом пошаговом руководстве показано, как использовать Firebase Cloud Messaging для реализации удаленных уведомлений (также называемых push-уведомлениями) в приложении Xamarin.Android. В нем показано, как реализовать различные классы, необходимые для обмена данными с Firebase Cloud Messaging (FCM), в примерах настройки манифеста Android для доступа к FCM и демонстрации нижестоящего обмена сообщениями с помощью консоли Firebase.
Обзор уведомлений FCM
В этом пошаговом руководстве будет создано базовое приложение с именем FCMClient , чтобы проиллюстрировать основные принципы обмена сообщениями FCM. FCMClient проверка для присутствия служб Google Play, получает маркеры регистрации из FCM, отображает удаленные уведомления, отправляемые из консоли Firebase, и подписывается на сообщения раздела:
В следующих разделах рассматриваются следующие области:
Фоновые уведомления
Сообщения раздела
Уведомления переднего плана
В этом пошаговом руководстве вы добавите функции в FCMClient и запустите его на устройстве или эмуляторе, чтобы понять, как он взаимодействует с FCM. Вы будете использовать ведение журнала для свидетелей динамических транзакций приложений с серверами FCM, и вы увидите, как уведомления создаются из сообщений FCM, которые вы вводите в графический интерфейс уведомлений консоли Firebase.
Требования
Вам будет полезно ознакомиться с различными типами сообщений , которые можно отправлять с помощью Firebase Cloud Messaging. Полезные данные сообщения определяют, как клиентское приложение будет получать и обрабатывать сообщение.
Прежде чем продолжить работу с этим пошаговым руководством, необходимо получить необходимые учетные данные для использования серверов FCM Google; этот процесс описан в Firebase Cloud Messaging. В частности, необходимо скачать файл google-services.json для использования с примером кода, представленного в этом пошаговом руководстве. Если вы еще не создали проект в консоли Firebase (или если вы еще не скачали файл google-services.json ), см . раздел Firebase Cloud Messaging.
Для запуска примера приложения потребуется тестовое устройство Android или эмулятор, который является compatibile с Firebase. Firebase Cloud Messaging поддерживает клиенты, работающие в Android 4.0 или более поздней версии, и эти устройства также должны иметь приложение Google Play Store (требуется служба Google Play 9.2.1 или более поздней версии). Если на устройстве еще не установлено приложение Google Play Store, посетите веб-сайт Google Play , чтобы скачать и установить его. Кроме того, вы можете использовать эмулятор пакета SDK для Android со службами Google Play, установленными вместо тестового устройства (вам не нужно устанавливать Google Play Store, если вы используете эмулятор пакета SDK для Android).
Запуск проекта приложения
Для начала создайте пустой проект Xamarin.Android с именем FCMClient. Если вы не знакомы с созданием проектов Xamarin.Android, см. статью Hello, Android. После создания нового приложения необходимо задать имя пакета и установить несколько пакетов NuGet, которые будут использоваться для взаимодействия с FCM.
Задание имени пакета
В Firebase Cloud Messaging вы указали имя пакета для приложения с поддержкой FCM. Это имя пакета также служит идентификатором приложения, связанного с ключом API. Настройте приложение для использования этого имени пакета:
Откройте свойства для проекта FCMClient .
На странице манифеста Android задайте имя пакета.
В следующем примере имя пакета имеет значение com.xamarin.fcmexample
:
При обновлении манифеста Android также проверка, чтобы убедиться, что Internet
разрешение включено.
Внимание
Клиентское приложение не сможет получить маркер регистрации из FCM, если это имя пакета не совпадает с именем пакета, введенным в консоль Firebase.
Добавление базового пакета служб Xamarin Google Play
Так как Firebase Cloud Messaging зависит от служб Google Play, служба Xamarin Google Play — базовый пакет NuGet необходимо добавить в проект Xamarin.Android. Вам потребуется версия 29.0.0.2 или более поздняя.
Если во время установки NuGet возникает ошибка, закройте проект FCMClient , снова откройте его и повторите установку NuGet.
При установке Xamarin.GooglePlayServices.Base также устанавливаются все необходимые зависимости. Измените MainActivity.cs и добавьте следующую using
инструкцию:
using Android.Gms.Common;
Эта инструкция делает класс в Xamarin.GooglePlayServices.Base доступным для кода FCMClient.GoogleApiAvailability
GoogleApiAvailability
используется для проверка для присутствия служб Google Play.
Добавление пакета обмена сообщениями Xamarin Firebase
Чтобы получать сообщения из FCM, пакет NuGet для обмена сообщениями Xamarin Firebase необходимо добавить в проект приложения. Без этого пакета приложение Android не может получать сообщения от серверов FCM.
При установке Xamarin.Firebase.Messaging также устанавливаются все необходимые зависимости.
Затем измените MainActivity.cs и добавьте следующие using
инструкции:
using Firebase.Messaging;
using Firebase.Iid;
using Android.Util;
Первые два оператора делают типы в пакете NuGet Xamarin.Firebase.Messaging доступным для кода FCMClient . Android.Util добавляет функции ведения журнала, которые будут использоваться для наблюдения за транзакциями с FMS.
Добавление JSON-файла сервисов Google
Следующим шагом является добавление файла google-services.json в корневой каталог проекта:
Скопируйте google-services.json в папку проекта.
Добавьте google-services.json в проект приложения (щелкните "Показать все файлы" в Обозреватель решений, щелкните правой кнопкой мыши google-services.json, а затем выберите "Включить в проект".
В окне обозревателя решений выберите файл google-services.json.
В области "Свойства" задайте действие сборки в GoogleServicesJson:
Примечание.
Если действие сборки GoogleServicesJson не отображается, сохраните и закройте решение, а затем снова откройте его.
При добавлении google-services.json в проект (и действие сборки GoogleServicesJson ) процесс сборки извлекает идентификатор клиента и ключ API, а затем добавляет эти учетные данные в объединенный и созданный AndroidManifest.xml , который находится в obj/Debug/android/AndroidManifest.xml. Этот процесс слияния автоматически добавляет все разрешения и другие элементы FCM, необходимые для подключения к серверам FCM.
Проверьте наличие служб Google Play и создайте канал уведомлений
Google рекомендует приложениям Android проверка для присутствия APK служб Google Play перед доступом к функциям Служб Google Play (дополнительные сведения см. в разделе "Проверка служб Google Play").
Сначала будет создан исходный макет пользовательского интерфейса приложения. Измените ресурсы/макет/Main.axml и замените его содержимое следующим XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:text=" "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/msgText"
android:textAppearance="?android:attr/textAppearanceMedium"
android:padding="10dp" />
</LinearLayout>
Это TextView
будет использоваться для отображения сообщений, указывающих, установлены ли службы Google Play. Сохраните изменения в Main.axml.
Измените MainActivity.cs и добавьте в класс следующие переменные экземпляра MainActivity
:
public class MainActivity : AppCompatActivity
{
static readonly string TAG = "MainActivity";
internal static readonly string CHANNEL_ID = "my_notification_channel";
internal static readonly int NOTIFICATION_ID = 100;
TextView msgText;
Переменные CHANNEL_ID
и NOTIFICATION_ID
будут использоваться в методе CreateNotificationChannel
, который будет добавлен MainActivity
далее в этом пошаговом руководстве.
В следующем примере метод проверяет доступность OnCreate
служб Google Play до попытки приложения использовать службы FCM.
Добавьте приведенный ниже метод в класс MainActivity
:
public bool IsPlayServicesAvailable ()
{
int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError (resultCode))
msgText.Text = GoogleApiAvailability.Instance.GetErrorString (resultCode);
else
{
msgText.Text = "This device is not supported";
Finish ();
}
return false;
}
else
{
msgText.Text = "Google Play Services is available.";
return true;
}
}
Этот код проверка устройство, чтобы узнать, установлен ли APK службы Google Play. Если он не установлен, в сообщении отображается TextBox
сообщение, которое указывает пользователю скачать APK из Магазина Google Play (или включить его в системных параметрах устройства).
Приложения, работающие на android 8.0 (уровень 26) или более поздней версии, должны создать канал уведомлений для публикации уведомлений. Добавьте следующий метод в MainActivity
класс, который создаст канал уведомлений (при необходимости):
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channel = new NotificationChannel(CHANNEL_ID,
"FCM Notifications",
NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
Замените метод OnCreate
следующим кодом:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
msgText = FindViewById<TextView> (Resource.Id.msgText);
IsPlayServicesAvailable ();
CreateNotificationChannel();
}
IsPlayServicesAvailable
вызывается в концеOnCreate
, чтобы службы Google Play проверка запускались при каждом запуске приложения. CreateNotificationChannel
Метод вызывается, чтобы убедиться, что канал уведомлений существует для устройств под управлением Android 8 или более поздней версии. Если у вашего приложения есть OnResume
метод, он также должен вызыватьсяIsPlayServicesAvailable
.OnResume
Полностью перестройте и запустите приложение. Если все настроено правильно, отобразится экран, который выглядит следующим образом:
Если вы не получите этот результат, убедитесь, что на устройстве установлен APK службы Google Play (дополнительные сведения см. в разделе "Настройка служб Google Play"). Кроме того, убедитесь, что вы добавили пакет Xamarin.Google.Play.Services.Base в проект FCMClient , как описано ранее.
Добавление приемника идентификатора экземпляра
Следующим шагом является добавление службы, которая расширяется FirebaseInstanceIdService
для обработки маркеров регистрации, смены и обновления маркеров регистрации Firebase. Служба FirebaseInstanceIdService
требуется для того, чтобы FCM мог отправлять сообщения на устройство. FirebaseInstanceIdService
При добавлении службы в клиентское приложение приложение будет автоматически получать сообщения FCM и отображать их в виде уведомлений всякий раз, когда приложение будет фоновым.
Объявление получателя в манифесте Android
Измените AndroidManifest.xml и вставьте следующие <receiver>
элементы в <application>
раздел:
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
Этот XML-код выполняет следующие действия:
FirebaseInstanceIdReceiver
Объявляет реализацию, которая предоставляет уникальный идентификатор для каждого экземпляра приложения. Этот получатель также выполняет проверку подлинности и авторизует действия.Объявляет внутреннюю
FirebaseInstanceIdInternalReceiver
реализацию, которая используется для безопасного запуска служб.Идентификатор приложения хранится в файле google-services.json, который был добавлен в проект. Привязки Xamarin.Android Firebase заменят маркер
${applicationId}
идентификатором приложения. Дополнительный код не требуется клиентскому приложению для предоставления идентификатора приложения.
Это FirebaseInstanceIdReceiver
объект WakefulBroadcastReceiver
, который получает FirebaseInstanceId
и события и FirebaseMessaging
передает их в класс, производный от FirebaseInstanceIdService
.
Реализация службы идентификаторов экземпляра Firebase
Работа по регистрации приложения в FCM обрабатывается пользовательской FirebaseInstanceIdService
службой, которую вы предоставляете.
FirebaseInstanceIdService
выполняет следующие действия:
Использует API идентификатора экземпляра для создания маркеров безопасности, которые разрешают клиентскому приложению доступ к FCM и серверу приложений. В обратном случае приложение возвращает маркер регистрации из FCM.
Перенаправит маркер регистрации на сервер приложений, если сервер приложений требует его.
Добавьте новый файл с именем MyFirebaseIIDService.cs и замените его код шаблона следующим образом:
using System;
using Android.App;
using Firebase.Iid;
using Android.Util;
namespace FCMClient
{
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{
const string TAG = "MyFirebaseIIDService";
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
}
void SendRegistrationToServer(string token)
{
// Add custom implementation, as needed.
}
}
}
Эта служба реализует OnTokenRefresh
метод, который вызывается при первоначальном создании или изменении маркера регистрации. При OnTokenRefresh
выполнении он извлекает последний маркер из FirebaseInstanceId.Instance.Token
свойства (который обновляется асинхронно FCM). В этом примере обновленный маркер регистрируется, чтобы его можно было просмотреть в окне вывода:
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
OnTokenRefresh
вызывается редко: он используется для обновления маркера в следующих обстоятельствах:
При установке или удалении приложения.
Когда пользователь удаляет данные приложения.
Когда приложение удаляет идентификатор экземпляра.
Когда безопасность маркера скомпрометирована.
Согласно документации по идентификатору экземпляра Google, служба идентификатора экземпляра FCM будет запрашивать периодические обновления маркера приложения (обычно каждые 6 месяцев).
OnTokenRefresh
также вызывает SendRegistrationToAppServer
связывание маркера регистрации пользователя с учетной записью на стороне сервера (при наличии), которая поддерживается приложением:
void SendRegistrationToAppServer (string token)
{
// Add custom implementation here as needed.
}
Так как эта реализация зависит от структуры сервера приложений, в этом примере представлен пустой текст метода. Если для сервера приложений требуются сведения о регистрации FCM, измените SendRegistrationToAppServer
для связывания маркера идентификатора экземпляра FCM пользователя с любой учетной записью на стороне сервера, поддерживаемой приложением. (Обратите внимание, что маркер непрозрачн для клиентского приложения.)
При отправке маркера на сервер приложений следует поддерживать логическое значение, SendRegistrationToAppServer
чтобы указать, был ли маркер отправлен на сервер. Если логическое значение равно false, SendRegistrationToAppServer
отправляет маркер на сервер приложений. В противном случае маркер уже был отправлен на сервер приложений в предыдущем вызове. В некоторых случаях (например, в этом FCMClient
примере) сервер приложений не нуждается в маркере. Поэтому этот метод не требуется для этого примера.
Реализация кода клиентского приложения
Теперь, когда службы-получатели находятся на месте, код клиентского приложения можно записать, чтобы воспользоваться преимуществами этих служб. В следующих разделах кнопка добавляется в пользовательский интерфейс для регистрации маркера регистрации (также называемого маркером идентификатора экземпляра), а дополнительные коды добавляются для MainActivity
просмотра Intent
сведений при запуске приложения из уведомления:
Маркеры журнала
Код, добавленный на этом шаге, предназначен только для демонстрационных целей. Производственное клиентское приложение не должно регистрировать маркеры регистрации. Измените resources/layout/Main.axml и добавьте следующее Button
объявление сразу после TextView
элемента:
<Button
android:id="@+id/logTokenButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Log Token" />
Добавьте указанный ниже код в конец метода MainActivity.OnCreate
:
var logTokenButton = FindViewById<Button>(Resource.Id.logTokenButton);
logTokenButton.Click += delegate {
Log.Debug(TAG, "InstanceID token: " + FirebaseInstanceId.Instance.Token);
};
Этот код регистрирует текущий маркер в окне вывода при нажатии кнопки маркера журнала.
Обработка намерений уведомлений
Когда пользователь нажимает уведомление, выданное из FCMClient, все данные, сопровождающие это уведомление, предоставляются в Intent
дополнительных функциях. Измените MainActivity.cs и добавьте следующий код в начало OnCreate
метода (перед вызовом IsPlayServicesAvailable
):
if (Intent.Extras != null)
{
foreach (var key in Intent.Extras.KeySet())
{
var value = Intent.Extras.GetString(key);
Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
}
}
Средство Intent
запуска приложения запускается, когда пользователь нажимает свое уведомление, поэтому этот код будет записывать любые сопровождающие данные в Intent
окне вывода. Если необходимо запустить другое Intent
, click_action
поле сообщения уведомления должно быть задано Intent
(средство Intent
запуска используется при отсутствии click_action
указанного значения).
Фоновые уведомления
Создайте и запустите приложение FCMClient . Отображается кнопка маркера журнала:
Нажмите кнопку "Маркер журнала". В окне вывода интегрированной среды разработки должно отображаться следующее сообщение:
Длинная строка, помеченная токеном, — это маркер идентификатора экземпляра, который вы вставляете в консоль Firebase. Выберите и скопируйте эту строку в буфер обмена. Если маркер идентификатора экземпляра не отображается, добавьте в начало OnCreate
метода следующую строку, чтобы убедиться, что google-services.json был правильно проанализирован:
Log.Debug(TAG, "google app id: " + GetString(Resource.String.google_app_id));
Значение google_app_id
, зарегистрированное в окне вывода, должно соответствовать mobilesdk_app_id
значению, записанному в google-services.json. Объект Resource.String.google_app_id
создается msbuild при обработке google-services.json.
Отправка сообщений
Войдите в консоль Firebase, выберите проект, щелкните уведомления и нажмите кнопку SEND YOUR FIRST MESSAGE:
На странице "Создание сообщения" введите текст сообщения и выберите одно устройство. Скопируйте маркер идентификатора экземпляра из выходного окна интегрированной среды разработки и вставьте его в поле маркера регистрации FCM консоли Firebase:
На устройстве Android (или эмуляторе) в фоновом режиме приложение коснитесь кнопки "Обзор Android" и коснувшись начального экрана. Когда устройство будет готово, нажмите кнопку SEND MESSAGE в консоли Firebase:
При отображении диалогового окна "Рецензирование" нажмите кнопку "ОТПРАВИТЬ". Значок уведомления должен отображаться в области уведомлений устройства (или эмулятора):
Откройте значок уведомления, чтобы просмотреть сообщение. Сообщение уведомления должно быть именно тем, что было введено в текстовое поле сообщения консоли Firebase:
Коснитесь значка уведомления, чтобы запустить приложение FCMClient . Дополнительные Intent
сведения, отправленные в FCMClient , перечислены в окне вывода интегрированной среды разработки:
В этом примере для ключа задано имя 41590732
пакета (com.xamarin.fcmexample collapse_key).
Если сообщение не получено, попробуйте удалить приложение FCMClient на устройстве (или эмуляторе) и повторите описанные выше действия.
Примечание.
При принудительном закрытии приложения FCM прекратит доставку уведомлений. Android запрещает трансляции фоновой службы непреднамеренно или ненужно запускать компоненты остановленных приложений. (Дополнительные сведения об этом поведении см. в разделе Запуск элементов управления в остановленных приложениях.) По этой причине необходимо вручную удалить приложение при каждом запуске и остановить его от сеанса отладки. Это заставляет FCM создавать новый маркер, чтобы сообщения продолжали получаться.
Добавление пользовательского значка уведомления по умолчанию
В предыдущем примере значок уведомления установлен на значок приложения. Следующий XML-код настраивает настраиваемый значок по умолчанию для уведомлений. Android отображает этот пользовательский значок по умолчанию для всех сообщений уведомлений, где значок уведомления не задан явным образом.
Чтобы добавить пользовательский значок уведомления по умолчанию, добавьте значок в каталог Resources/drawable , измените AndroidManifest.xml и вставьте следующий <meta-data>
элемент в <application>
раздел:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
В этом примере значок уведомления, который находится в resources/drawable/ic_stat_ic_notification.png , будет использоваться в качестве значка пользовательского уведомления по умолчанию. Если настраиваемый значок по умолчанию не настроен в AndroidManifest.xml и в полезных данных уведомления не задан, Android использует значок приложения в качестве значка уведомления (как показано на снимке экрана выше значка уведомления).
Обработка сообщений раздела
Код, написанный до сих пор, обрабатывает маркеры регистрации и добавляет функции удаленного уведомления в приложение. В следующем примере добавляется код, который прослушивает сообщения тем и пересылает их пользователю в виде удаленных уведомлений. Сообщения раздела — это сообщения FCM, отправляемые на одно или несколько устройств, которые подписываются на определенный раздел. Дополнительные сведения о сообщениях раздела см. в разделе "Обмен сообщениями тем".
Оформление подписки на тему
Измените resources/layout/Main.axml и добавьте следующее Button
объявление сразу после предыдущего Button
элемента:
<Button
android:id="@+id/subscribeButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:text="Subscribe to Notifications" />
Этот XML-код добавляет кнопку "Подписаться на уведомление " в макет.
Измените MainActivity.cs и добавьте следующий код в конец OnCreate
метода:
var subscribeButton = FindViewById<Button>(Resource.Id.subscribeButton);
subscribeButton.Click += delegate {
FirebaseMessaging.Instance.SubscribeToTopic("news");
Log.Debug(TAG, "Subscribed to remote notifications");
};
Этот код находит кнопку "Подписаться на уведомление " в макете и назначает обработчику щелчков коду, который вызывает FirebaseMessaging.Instance.SubscribeToTopic
, передавая подписанный раздел, новости. Когда пользователь нажимает кнопку "Подписаться ", приложение подписывается на раздел новостей . В следующем разделе сообщение о новостях будет отправлено из графического интерфейса графического интерфейса уведомлений консоли Firebase.
Отправка сообщения раздела
Удалите приложение, перестроите его и снова запустите его. Нажмите кнопку "Подписаться на уведомления" :
Если приложение успешно подписано, в окне вывода интегрированной среды разработки вы увидите, что синхронизация разделов успешно выполнена .
Чтобы отправить сообщение раздела, выполните следующие действия.
В консоли Firebase щелкните NEW MESSAGE.
На странице "Создание сообщения" введите текст сообщения и выберите раздел.
В раскрывающемся меню раздела выберите встроенный раздел, новости:
На устройстве Android (или эмуляторе) в фоновом режиме приложение коснитесь кнопки "Обзор Android" и коснувшись начального экрана.
Когда устройство будет готово, нажмите кнопку SEND MESSAGE в консоли Firebase.
Проверьте окно вывода интегрированной среды разработки, чтобы просмотреть /темы и новости в выходных данных журнала:
Когда это сообщение отображается в окне вывода, значок уведомления также должен отображаться в области уведомлений на устройстве Android. Откройте значок уведомления, чтобы просмотреть сообщение раздела:
Если сообщение не получено, попробуйте удалить приложение FCMClient на устройстве (или эмуляторе) и повторите описанные выше действия.
Уведомления переднего плана
Чтобы получать уведомления в приложениях переднего плана, необходимо реализовать FirebaseMessagingService
. Эта служба также требуется для получения полезных данных и отправки вышестоящий сообщений. В следующих примерах показано, как реализовать службу, которая расширяется FirebaseMessagingService
. Полученное приложение сможет обрабатывать удаленные уведомления во время работы на переднем плане.
Реализация FirebaseMessagingService
Служба FirebaseMessagingService
отвечает за получение и обработку сообщений из Firebase. Каждое приложение должно подклассить этот тип и переопределить OnMessageReceived
для обработки входящего сообщения. Когда приложение находится на переднем плане, OnMessageReceived
обратный вызов всегда будет обрабатывать сообщение.
Примечание.
Приложения имеют только 10 секунд, в которых обрабатывается входящее облачное сообщение Firebase. Любая работа, которая занимает больше времени, чем это должно быть запланировано для фонового выполнения, с помощью библиотеки, такой как планировщик заданий Android или диспетчер заданий Firebase.
Добавьте новый файл с именем MyFirebaseMessagingService.cs и замените его код шаблона следующим образом:
using System;
using Android.App;
using Android.Content;
using Android.Media;
using Android.Util;
using Firebase.Messaging;
namespace FCMClient
{
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(TAG, "From: " + message.From);
Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
}
}
}
Обратите внимание, что фильтр намерений MESSAGING_EVENT
должен быть объявлен таким образом, чтобы новые сообщения FCM направлялись в MyFirebaseMessagingService
:
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
Когда клиентское приложение получает сообщение из FCM, OnMessageReceived
извлекает содержимое сообщения из переданного RemoteMessage
объекта, вызывая его GetNotification
метод. Затем он регистрирует содержимое сообщения, чтобы его можно было просмотреть в окне выходных данных интегрированной среды разработки:
var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);
Примечание.
Если вы устанавливаете точки останова в FirebaseMessagingService
, сеанс отладки может или не попал в эти точки останова из-за того, как FCM доставляет сообщения.
Отправка другого сообщения
Удалите приложение, перестроите его, запустите его еще раз и выполните следующие действия, чтобы отправить другое сообщение:
В консоли Firebase щелкните NEW MESSAGE.
На странице "Создание сообщения" введите текст сообщения и выберите одно устройство.
Скопируйте строку токена из окна вывода интегрированной среды разработки и вставьте ее в поле маркера регистрации FCM консоли Firebase, как и раньше.
Убедитесь, что приложение запущено на переднем плане, а затем нажмите кнопку SEND MESSAGE в консоли Firebase:
При отображении диалогового окна "Рецензирование" нажмите кнопку "ОТПРАВИТЬ".
Входящее сообщение регистрируется в окне вывода интегрированной среды разработки:
Добавление локального отправителя уведомлений
В этом оставшемся примере входящие сообщения FCM будут преобразованы в локальное уведомление, которое запускается во время работы приложения на переднем плане. Измените MyFirebaseMessageService.cs и добавьте следующие using
инструкции:
using FCMClient;
using System.Collections.Generic;
Добавьте следующий метод к MyFirebaseMessagingService
:
void SendNotification(string messageBody, IDictionary<string, string> data)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
foreach (var key in data.Keys)
{
intent.PutExtra(key, data[key]);
}
var pendingIntent = PendingIntent.GetActivity(this,
MainActivity.NOTIFICATION_ID,
intent,
PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
.SetContentTitle("FCM Message")
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}
Чтобы отличить это уведомление от фоновых уведомлений, этот код помечает уведомления значком, который отличается от значка приложения. Добавьте файл ic_stat_ic_notification.png в resources/drawable и добавьте его в проект FCMClient .
Метод SendNotification
используется NotificationCompat.Builder
для создания уведомления и NotificationManagerCompat
используется для запуска уведомления. Уведомление содержит сообщение PendingIntent
, позволяющее пользователю открывать приложение и просматривать содержимое строки, переданной в messageBody
. Дополнительные сведения см. в NotificationCompat.Builder
разделе "Локальные уведомления".
SendNotification
Вызовите метод в конце OnMessageReceived
метода:
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(TAG, "From: " + message.From);
var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);
SendNotification(body, message.Data);
}
В результате этих изменений будет выполняться всякий раз, SendNotification
когда уведомление получено, пока приложение находится на переднем плане, и уведомление появится в области уведомлений.
Когда приложение находится в фоновом режиме, полезные данные сообщения определяют, как обрабатывается сообщение:
- Уведомление — сообщения будут отправляться в системную область. Появится локальное уведомление. Когда пользователь нажимает уведомление, приложение запустится.
- Данные — сообщения будут обрабатываться
OnMessageReceived
. - Оба — сообщения, имеющие как уведомление, так и полезные данные, будут доставлены в системную область. Когда приложение запускается, полезные данные будут отображаться в
Extras
Intent
том, что использовалось для запуска приложения.
В этом примере, если приложение в фоновом режиме, будет выполняться, SendNotification
если сообщение содержит полезные данные. В противном случае будет запущено фоновое уведомление (иллюстрированное ранее в этом пошаговом руководстве).
Отправка последнего сообщения
Удалите приложение, перестроите его, снова запустите его, а затем выполните следующие действия, чтобы отправить последнее сообщение:
В консоли Firebase щелкните NEW MESSAGE.
На странице "Создание сообщения" введите текст сообщения и выберите одно устройство.
Скопируйте строку токена из окна вывода интегрированной среды разработки и вставьте ее в поле маркера регистрации FCM консоли Firebase, как и раньше.
Убедитесь, что приложение запущено на переднем плане, а затем нажмите кнопку SEND MESSAGE в консоли Firebase:
На этот раз сообщение, зарегистрированное в окне вывода, также упаковано в новое уведомление: значок уведомления отображается в области уведомлений во время работы приложения на переднем плане:
При открытии уведомления вы увидите последнее сообщение, отправленное из графического интерфейса уведомлений консоли Firebase:
Отключение от FCM
Чтобы отменить подписку из раздела, вызовите метод UnsubscribeFromTopic в классе FirebaseMessaging . Например, чтобы отменить подписку из раздела новостей, подписанного ранее, к макету можно добавить кнопку отмены подписки со следующим кодом обработчика:
var unSubscribeButton = FindViewById<Button>(Resource.Id.unsubscribeButton);
unSubscribeButton.Click += delegate {
FirebaseMessaging.Instance.UnsubscribeFromTopic("news");
Log.Debug(TAG, "Unsubscribed from remote notifications");
};
Чтобы полностью отменить регистрацию устройства из FCM, удалите идентификатор экземпляра, вызвав метод DeleteInstanceId в классе FirebaseInstanceId . Например:
FirebaseInstanceId.Instance.DeleteInstanceId();
Этот метод вызывает удаление идентификатора экземпляра и связанных с ним данных. В результате периодические отправки данных FCM на устройство остановлены.
Устранение неполадок
Ниже описаны проблемы и обходные пути, которые могут возникнуть при использовании Firebase Cloud Messaging с Xamarin.Android.
FirebaseApp не инициализирован
В некоторых случаях может появить следующее сообщение об ошибке:
Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.
Это известная проблема, с помощью очистки решения и перестроения проекта (сборка > чистого решения, сборка > решения для перестроения).
Итоги
В этом пошаговом руководстве описаны шаги по реализации удаленных уведомлений Firebase Cloud Messaging в приложении Xamarin.Android. В нем описано, как установить необходимые пакеты, необходимые для обмена данными FCM, и в нем объясняется, как настроить манифест Android для доступа к серверам FCM. В нем представлен пример кода, иллюстрирующий проверка для присутствия служб Google Play. В нем показано, как реализовать службу прослушивателя идентификаторов экземпляра, которая ведет переговоры с FCM для маркера регистрации, и объяснила, как этот код создает фоновые уведомления во время фона приложения. В нем объясняется, как подписаться на сообщения тем, и он предоставил пример реализации службы прослушивателя сообщений, которая используется для получения и отображения удаленных уведомлений во время работы приложения на переднем плане.