Удаленные уведомления с помощью Firebase Cloud Messaging

В этом пошаговом руководстве показано, как использовать Firebase Cloud Messaging для реализации удаленных уведомлений (также называемых push-уведомлениями) в приложении Xamarin.Android. В нем показано, как реализовать различные классы, необходимые для обмена данными с Firebase Cloud Messaging (FCM), в примерах настройки манифеста Android для доступа к FCM и демонстрации нижестоящего обмена сообщениями с помощью консоли Firebase.

Обзор уведомлений FCM

В этом пошаговом руководстве будет создано базовое приложение с именем FCMClient , чтобы проиллюстрировать основные принципы обмена сообщениями FCM. FCMClient проверка для присутствия служб Google Play, получает маркеры регистрации из FCM, отображает удаленные уведомления, отправляемые из консоли Firebase, и подписывается на сообщения раздела:

Example screenshot of app

В следующих разделах рассматриваются следующие области:

  1. Фоновые уведомления

  2. Сообщения раздела

  3. Уведомления переднего плана

В этом пошаговом руководстве вы добавите функции в 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. Настройте приложение для использования этого имени пакета:

  1. Откройте свойства для проекта FCMClient .

  2. На странице манифеста Android задайте имя пакета.

В следующем примере имя пакета имеет значение com.xamarin.fcmexample:

Setting the package name

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

Внимание

Клиентское приложение не сможет получить маркер регистрации из FCM, если это имя пакета не совпадает с именем пакета, введенным в консоль Firebase.

Добавление базового пакета служб Xamarin Google Play

Так как Firebase Cloud Messaging зависит от служб Google Play, служба Xamarin Google Play — базовый пакет NuGet необходимо добавить в проект Xamarin.Android. Вам потребуется версия 29.0.0.2 или более поздняя.

  1. В Visual Studio щелкните правой кнопкой мыши ссылки > на управление пакетами NuGet ....

  2. Щелкните вкладку "Обзор" и найдите Xamarin.GooglePlayServices.Base.

  3. Установите этот пакет в проект FCMClient :

    Installing Google Play Services Base

Если во время установки 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.

  1. В Visual Studio щелкните правой кнопкой мыши ссылки > на управление пакетами NuGet ....

  2. Найдите Xamarin.Firebase.Messaging.

  3. Установите этот пакет в проект FCMClient :

    Installing Xamarin Firebase Messaging

При установке 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 в корневой каталог проекта:

  1. Скопируйте google-services.json в папку проекта.

  2. Добавьте google-services.json в проект приложения (щелкните "Показать все файлы" в Обозреватель решений, щелкните правой кнопкой мыши google-services.json, а затем выберите "Включить в проект".

  3. В окне обозревателя решений выберите файл google-services.json.

  4. В области "Свойства" задайте действиесборки в GoogleServicesJson:

    Setting the build action to 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 Полностью перестройте и запустите приложение. Если все настроено правильно, отобразится экран, который выглядит следующим образом:

App indicates that Google Play Services is available

Если вы не получите этот результат, убедитесь, что на устройстве установлен 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 выполняет следующие действия:

  1. Использует API идентификатора экземпляра для создания маркеров безопасности, которые разрешают клиентскому приложению доступ к FCM и серверу приложений. В обратном случае приложение возвращает маркер регистрации из FCM.

  2. Перенаправит маркер регистрации на сервер приложений, если сервер приложений требует его.

Добавьте новый файл с именем 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 сведений при запуске приложения из уведомления:

Log Token button added to app screen

Маркеры журнала

Код, добавленный на этом шаге, предназначен только для демонстрационных целей. Производственное клиентское приложение не должно регистрировать маркеры регистрации. Измените 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 . Отображается кнопка маркера журнала:

Log Token button is displayed

Нажмите кнопку "Маркер журнала". В окне вывода интегрированной среды разработки должно отображаться следующее сообщение:

Instance ID token displayed in Output window

Длинная строка, помеченная токеном, — это маркер идентификатора экземпляра, который вы вставляете в консоль 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:

Send Your First Message button

На странице "Создание сообщения" введите текст сообщения и выберите одно устройство. Скопируйте маркер идентификатора экземпляра из выходного окна интегрированной среды разработки и вставьте его в поле маркера регистрации FCM консоли Firebase:

Compose message dialog

На устройстве Android (или эмуляторе) в фоновом режиме приложение коснитесь кнопки "Обзор Android" и коснувшись начального экрана. Когда устройство будет готово, нажмите кнопку SEND MESSAGE в консоли Firebase:

Send message button

При отображении диалогового окна "Рецензирование" нажмите кнопку "ОТПРАВИТЬ". Значок уведомления должен отображаться в области уведомлений устройства (или эмулятора):

Notification icon is shown

Откройте значок уведомления, чтобы просмотреть сообщение. Сообщение уведомления должно быть именно тем, что было введено в текстовое поле сообщения консоли Firebase:

Notification message is displayed on the device

Коснитесь значка уведомления, чтобы запустить приложение FCMClient . Дополнительные Intent сведения, отправленные в FCMClient , перечислены в окне вывода интегрированной среды разработки:

Intent extras lists from key, message ID, and collapse key

В этом примере для ключа задано имя 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.

Отправка сообщения раздела

Удалите приложение, перестроите его и снова запустите его. Нажмите кнопку "Подписаться на уведомления" :

Subscribe to Notifications button

Если приложение успешно подписано, в окне вывода интегрированной среды разработки вы увидите, что синхронизация разделов успешно выполнена .

Output window shows topic sync succeeded message

Чтобы отправить сообщение раздела, выполните следующие действия.

  1. В консоли Firebase щелкните NEW MESSAGE.

  2. На странице "Создание сообщения" введите текст сообщения и выберите раздел.

  3. В раскрывающемся меню раздела выберите встроенный раздел, новости:

    Selecting the news topic

  4. На устройстве Android (или эмуляторе) в фоновом режиме приложение коснитесь кнопки "Обзор Android" и коснувшись начального экрана.

  5. Когда устройство будет готово, нажмите кнопку SEND MESSAGE в консоли Firebase.

  6. Проверьте окно вывода интегрированной среды разработки, чтобы просмотреть /темы и новости в выходных данных журнала:

    Message from /topic/news is shown

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

The topic message appears as a notification

Если сообщение не получено, попробуйте удалить приложение 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 доставляет сообщения.

Отправка другого сообщения

Удалите приложение, перестроите его, запустите его еще раз и выполните следующие действия, чтобы отправить другое сообщение:

  1. В консоли Firebase щелкните NEW MESSAGE.

  2. На странице "Создание сообщения" введите текст сообщения и выберите одно устройство.

  3. Скопируйте строку токена из окна вывода интегрированной среды разработки и вставьте ее в поле маркера регистрации FCM консоли Firebase, как и раньше.

  4. Убедитесь, что приложение запущено на переднем плане, а затем нажмите кнопку SEND MESSAGE в консоли Firebase:

    Sending another message from the Console

  5. При отображении диалогового окна "Рецензирование" нажмите кнопку "ОТПРАВИТЬ".

  6. Входящее сообщение регистрируется в окне вывода интегрированной среды разработки:

    Message body printed to output window

Добавление локального отправителя уведомлений

В этом оставшемся примере входящие сообщения 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.
  • Оба — сообщения, имеющие как уведомление, так и полезные данные, будут доставлены в системную область. Когда приложение запускается, полезные данные будут отображаться в ExtrasIntent том, что использовалось для запуска приложения.

В этом примере, если приложение в фоновом режиме, будет выполняться, SendNotification если сообщение содержит полезные данные. В противном случае будет запущено фоновое уведомление (иллюстрированное ранее в этом пошаговом руководстве).

Отправка последнего сообщения

Удалите приложение, перестроите его, снова запустите его, а затем выполните следующие действия, чтобы отправить последнее сообщение:

  1. В консоли Firebase щелкните NEW MESSAGE.

  2. На странице "Создание сообщения" введите текст сообщения и выберите одно устройство.

  3. Скопируйте строку токена из окна вывода интегрированной среды разработки и вставьте ее в поле маркера регистрации FCM консоли Firebase, как и раньше.

  4. Убедитесь, что приложение запущено на переднем плане, а затем нажмите кнопку SEND MESSAGE в консоли Firebase:

    Sending the foreground message

На этот раз сообщение, зарегистрированное в окне вывода, также упаковано в новое уведомление: значок уведомления отображается в области уведомлений во время работы приложения на переднем плане:

Notification icon for foreground message

При открытии уведомления вы увидите последнее сообщение, отправленное из графического интерфейса уведомлений консоли Firebase:

Foreground notification shown with foreground icon

Отключение от 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 для маркера регистрации, и объяснила, как этот код создает фоновые уведомления во время фона приложения. В нем объясняется, как подписаться на сообщения тем, и он предоставил пример реализации службы прослушивателя сообщений, которая используется для получения и отображения удаленных уведомлений во время работы приложения на переднем плане.