共用方式為


使用 Firebase 雲端通訊的遠端通知

本逐步解說提供如何使用 Firebase 雲端通訊在 Xamarin.Android 應用程式中實作遠端通知(也稱為推播通知)的逐步說明。 它說明如何實作與 Firebase 雲端通訊 (FCM) 通訊所需的各種類別,提供如何設定 Android 指令清單以存取 FCM 的範例,以及示範使用 Firebase 控制台的下游傳訊。

FCM 通知概觀

在本逐步解說中,將會建立名為 FCMClient 的基本應用程式,以說明 FCM 傳訊的基本概念。 FCMClient 會檢查 Google Play 服務是否存在、從 FCM 接收註冊令牌、顯示您從 Firebase 控制台傳送的遠端通知,以及訂閱主題訊息:

應用程式的範例螢幕快照

將會探索下列主題領域:

  1. 背景通知

  2. 主題訊息

  3. 前景通知

在本逐步解說期間,您會以累加方式將功能新增至 FCMClient ,並在裝置或模擬器上執行此功能,以瞭解它與 FCM 的互動方式。 您將使用記錄來見證與 FCM 伺服器的即時應用程式交易,並觀察如何從您輸入 Firebase 控制台通知 GUI 的 FCM 訊息產生通知。

需求

若要熟悉 Firebase 雲端傳訊可以傳送的不同類型訊息 ,將很有説明。 訊息的承載將決定用戶端應用程式接收和處理訊息的方式。

您必須先取得必要的認證才能繼續進行本逐步解說,才能使用Google的 FCM 伺服器;此程式會在 Firebase 雲端傳訊說明。 特別是,您必須下載 google-services.json 檔案,以搭配本逐步解說中所示的範例程式代碼使用。 如果您尚未在 Firebase 控制台中建立專案(或尚未下載 google-services.json 檔案),請參閱 Firebase 雲端通訊

若要執行範例應用程式,您需要與 Firebase 相符合的 Android 測試裝置或模擬器。 Firebase 雲端通訊支援在 Android 4.0 或更高版本上執行的用戶端,而且這些裝置也必須安裝 Google Play Store 應用程式(需要 Google Play Services 9.2.1 或更新版本)。 如果您尚未在您的裝置上安裝 Google Play Store 應用程式,請流覽 Google Play 網站以下載並安裝。 或者,您可以使用已安裝 Google Play 服務的 Android SDK 模擬器,而不是測試裝置(如果您使用 Android SDK 模擬器,則不需要安裝 Google Play Store)。

啟動應用程式專案

若要開始,請建立名為 FCMClient 的新空白 Xamarin.Android 專案。 如果您不熟悉建立 Xamarin.Android 專案,請參閱 Hello、 Android。 建立新的應用程式之後,下一個步驟是設定套件名稱,並安裝數個將用於與 FCM 通訊的 NuGet 套件。

設定套件名稱

Firebase 雲端通訊中,您為已啟用 FCM 的應用程式指定套件名稱。 此套件名稱也會做為與 API 金鑰相關聯的應用程式識別碼。 將應用程式設定為使用此套件名稱:

  1. 開啟 FCMClient 項目的屬性

  2. 在 [ Android 指令清單] 頁面中,設定套件名稱。

在下列範例中,套件名稱會設定為 com.xamarin.fcmexample

設定套件名稱

當您更新 Android 指令清單時,也請檢查以確定 Internet 已啟用許可權。

重要

如果此套件名稱與在 Firebase 控制台中輸入的套件名稱不 完全 相符,用戶端應用程式將無法從 FCM 接收註冊令牌。

新增 Xamarin Google Play 服務基底套件

由於 Firebase 雲端通訊相依於 Google Play 服務, 因此 Xamarin Google Play 服務 - 基礎 NuGet 套件必須新增至 Xamarin.Android 專案。 您將需要 29.0.0.2 版或更新版本。

  1. 在 Visual Studio 中,以滑鼠右鍵按兩下 [ 參考 > 管理 NuGet 套件...]。

  2. 按兩下 [ 瀏覽] 索引標籤,然後搜尋 Xamarin.GooglePlayServices.Base

  3. 將此套件安裝到 FCMClient 專案中:

    安裝Google Play服務基礎

如果您在安裝 NuGet 期間收到錯誤,請關閉 FCMClient 專案,再次開啟它,然後重試 NuGet 安裝。

當您安裝 Xamarin.GooglePlayServices.Base 時,也會安裝所有必要的相依性。 編輯 MainActivity.cs 並新增下列 using 語句:

using Android.Gms.Common;

此語句會GoogleApiAvailability讓 Xamarin.GooglePlayServices.Base 中的 類別可供 FCMClient 程式代碼使用。 GoogleApiAvailability 是用來檢查Google Play服務是否存在。

新增 Xamarin Firebase 傳訊套件

若要從 FCM 接收訊息, 必須將 Xamarin Firebase - 傳訊 NuGet 套件新增至應用程式專案。 如果沒有此套件,Android 應用程式就無法從 FCM 伺服器接收訊息。

  1. 在 Visual Studio 中,以滑鼠右鍵按兩下 [ 參考 > 管理 NuGet 套件...]。

  2. 搜尋 Xamarin.Firebase.Messaging

  3. 將此套件安裝到 FCMClient 專案中:

    安裝 Xamarin Firebase 傳訊

當您安裝 Xamarin.Firebase.Messaging 時,也會安裝所有必要的相依性。

接下來,編輯 MainActivity.cs 並新增下列 using 語句:

using Firebase.Messaging;
using Firebase.Iid;
using Android.Util;

前兩個語句會讓 Xamarin.Firebase.Messaging NuGet 套件中的類型可供 FCMClient 程式代碼使用Android.Util 新增記錄功能,將用來觀察 FMS 的交易。

新增Google Services JSON 檔案

下一個步驟是將 google-services.json 檔案新增至專案的根目錄:

  1. 將google-services.json複製到項目資料夾。

  2. 將google-services.json新增至應用程式專案(按兩下[顯示方案總管 中的所有檔案],以滑鼠右鍵按兩下google-services.json,然後選取[在專案中包含]。

  3. [方案總管] 視窗中選取 [google-services.json]。

  4. 在 [ 屬性] 窗格中,將 [建置 動作 ] 設定為 GoogleServicesJson

    將建置動作設定為GoogleServicesJson

    注意

    如果未顯示 GoogleServicesJson 建置動作,請儲存並關閉解決方案,然後重新開啟它。

google-services.json新增至專案時(且已設定 GoogleServicesJson 建置動作),建置程式會擷取用戶端標識碼和 API 密鑰,然後將這些認證新增至位於 obj/Debug/android/AndroidManifest.xml 的合併/產生的AndroidManifest.xml 此合併程式會自動新增連線到 FCM 伺服器所需的任何許可權和其他 FCM 元素。

檢查Google Play服務並建立通知頻道

Google 建議 Android 應用程式先檢查 Google Play 服務 APK 是否存在,再存取 Google Play 服務功能(如需詳細資訊,請參閱 檢查 Google Play 服務)。

系統會先建立應用程式UI的初始版面配置。 編輯 Resources/layout/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_IDNOTIFICATION_ID將用於稍後在本逐步解說中將新增至 MainActivity 的方法CreateNotificationChannel中。

在下列範例中, OnCreate 方法會在應用程式嘗試使用 FCM 服務之前,先確認 Google Play 服務可供使用。 將下列方法新增至 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;
    }
}

此程式代碼會檢查裝置,以查看是否已安裝Google Play服務 APK。 如果未安裝,則會在 中 TextBox 顯示訊息,指示使用者從 Google Play 商店下載 APK(或在裝置的系統設定中啟用它)。

在 Android 8.0 (API 層級 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 ,以確保執行Android8或更新版本的裝置有通知通道存在。 如果應用程式有 OnResume 方法,它應該從呼叫 IsPlayServicesAvailable OnResume 。 完全重建並執行應用程式。 如果所有設定都正確,您應該會看到類似下列螢幕快照的畫面:

應用程式指出Google Play服務可供使用

如果您未取得此結果,請確認您的裝置上已安裝Google Play服務 APK(如需詳細資訊,請參閱 設定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} 取代為應用程式識別碼;客戶端應用程式不需要額外的程式碼來提供應用程式識別碼。

FirebaseInstanceIdReceiverWakefulBroadcastReceiver 接收 FirebaseInstanceIdFirebaseMessaging 事件的 ,並將其傳遞至衍生自 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 應用程式伺服器不需要令牌;因此,此範例不需要此方法。

實作用戶端應用程式程序代碼

既然接收者服務已就緒,就可以撰寫用戶端應用程式程式代碼來利用這些服務。 在下列各節中,系統會將按鈕新增至 UI 以記錄註冊令牌(也稱為 實例識別碼令牌),並在應用程式從通知啟動時新增 MainActivity 更多程式碼以檢視 Intent 資訊:

新增至應用程式畫面的 [記錄令牌] 按鈕

記錄令牌

在此步驟中新增的程式代碼僅供示範之用–生產用戶端應用程式不需要記錄註冊令牌。 編輯 Resources/layout/Main.axml,並在 元素後面TextView立即新增下列Button宣告:

<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 ,通知訊息的字段必須設定為該Intent欄位(未指定時click_action會使用啟動器Intentclick_action)。

背景通知

建置 並執行 FCMClient 應用程式。 [ 記錄令牌 ] 按鈕隨即顯示:

[記錄令牌] 按鈕隨即顯示

點選 [ 記錄令牌 ] 按鈕。 IDE 輸出視窗中應該會顯示如下的訊息:

[輸出] 視窗中顯示的實例識別碼令牌

標示為 令牌 的長字串是您要貼到 Firebase 控制台的實體識別碼令牌 , 選取並將此字串複製到剪貼簿。 如果您沒有看到實例標識碼令牌,請將下列這一行新增至 方法頂端 OnCreate ,以確認 已正確剖析google-services.json

Log.Debug(TAG, "google app id: " + GetString(Resource.String.google_app_id));

google_app_id記錄至輸出視窗的值應該符合mobilesdk_app_idgoogle-services.json中記錄的值。 處理Resource.String.google_app_idgoogle-services.json,msbuild 會產生 。

傳送訊息

登入 Firebase 控制台,選取您的專案,按兩下 [通知],然後按兩下 [傳送您的第一個訊息]:

傳送您的第一個訊息按鈕

在 [ 撰寫訊息 ] 頁面上,輸入消息正文,然後選取 [單一裝置]。 從 IDE 輸出視窗複製實例識別碼令牌,並將其貼到 Firebase 控制台的 FCM 註冊令牌 欄位中:

撰寫訊息對話框

在Android裝置(或模擬器)上,點選 [Android 概觀 ] 按鈕並觸控主畫面來背景應用程式。 裝置就緒時,按兩下 Firebase 控制台中的 [ 傳送訊息 ]:

傳送訊息按鈕

顯示 [ 檢閱訊息 ] 對話框時,按兩下 [ 傳送]。 通知圖示應該會出現在裝置的通知區域中(或模擬器):

顯示通知圖示

開啟通知圖示以檢視訊息。 通知訊息應該完全符合 Firebase 控制台的 [訊息] 文字 欄位中所輸入的內容:

通知訊息會顯示在裝置上

點選通知圖示以啟動 FCMClient 應用程式。 傳送 IntentFCMClient 的額外項目會列在 IDE 輸出視窗中:

來自金鑰、訊息識別碼和折疊索引鍵的意圖額外項目清單

在此範例中, from 機碼會設定為應用程式的 Firebase 項目編號(在此範例中為 41590732),而 collapse_key 會設定為其套件名稱 (com.xamarin.fcmexample)。 如果您沒有收到訊息,請嘗試刪除 裝置上的 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 控制台通知 GUI 傳送新聞 主題訊息。

傳送主題訊息

卸載應用程式、重建應用程式,然後再次執行。 按兩下 [ 訂閱通知 ] 按鈕:

訂閱通知按鈕

如果應用程式已成功訂閱,您應該會在 IDE 輸出視窗中看到 主題同步成功

輸出視窗顯示主題同步成功訊息

使用下列步驟傳送主題訊息:

  1. 在 Firebase 控制台中,按兩下 [ 新增訊息]。

  2. 在 [ 撰寫訊息 ] 頁面上,輸入消息正文,然後選取 [ 主題]。

  3. 在 [主題] 下拉功能表中,選取內建主題新聞

    選取新聞主題

  4. 在Android裝置(或模擬器)上,點選 [Android 概觀 ] 按鈕並觸控主畫面來背景應用程式。

  5. 裝置就緒時,按兩下 Firebase 控制台中的 [ 傳送訊息 ]。

  6. 檢查 IDE 輸出視窗,以檢視 記錄輸出中的 /topics/news

    顯示 /topic/news 的訊息

當在輸出視窗中看到此訊息時,通知圖示也應該出現在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呼叫其 GetNotification 方法,從傳入RemoteMessage的物件擷取訊息內容。 接下來,它會記錄訊息內容,以便在 IDE 輸出視窗中檢視:

var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);

注意

如果您在 中 FirebaseMessagingService設定斷點,您的偵錯會話可能會因為 FCM 傳遞訊息的方式而無法叫用這些斷點。

傳送另一則訊息

卸載應用程式、重建應用程式、再次執行應用程式,然後遵循下列步驟來傳送另一則訊息:

  1. 在 Firebase 控制台中,按兩下 [ 新增訊息]。

  2. 在 [ 撰寫訊息 ] 頁面上,輸入消息正文,然後選取 [單一裝置]。

  3. 從 IDE 輸出視窗複製令牌字串,並將它貼到 Firebase 控制台的 FCM 註冊令牌 欄位中,如下所示。

  4. 確定應用程式正在前景執行,然後按兩下 Firebase 控制台中的 [ 傳送訊息 ]:

    從主控台傳送另一則訊息

  5. 顯示 [ 檢閱訊息 ] 對話框時,按兩下 [ 傳送]。

  6. 傳入訊息會記錄至 IDE 輸出視窗:

    列印至輸出視窗的訊息本文

新增本機通知寄件者

在此剩餘的範例中,傳入的 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 控制台中,按兩下 [ 新增訊息]。

  2. 在 [ 撰寫訊息 ] 頁面上,輸入消息正文,然後選取 [單一裝置]。

  3. 從 IDE 輸出視窗複製令牌字串,並將它貼到 Firebase 控制台的 FCM 註冊令牌 欄位中,如下所示。

  4. 確定應用程式正在前景執行,然後按兩下 Firebase 控制台中的 [ 傳送訊息 ]:

    傳送前景訊息

這一次,在輸出視窗中記錄的訊息也會封裝在新的通知中–當應用程式在前景執行時,通知圖示會出現在通知匣中:

前景訊息的通知圖示

當您開啟通知時,應該會看到從 Firebase 控制台通知 GUI 傳送的最後一則訊息:

前景通知以前景圖示顯示

中斷與 FCM 的連線

若要取消訂閱主題,請在 FirebaseMessaging 類別上呼叫 UnsubscribeFromTopic 方法。 例如,若要取消訂閱稍早訂閱的新聞主題,可以使用下列處理程式程式代碼將取消訂閱按鈕新增至版面配置:

var unSubscribeButton = FindViewById<Button>(Resource.Id.unsubscribeButton);
unSubscribeButton.Click += delegate {
    FirebaseMessaging.Instance.UnsubscribeFromTopic("news");
    Log.Debug(TAG, "Unsubscribed from remote notifications");
};

若要從 FCM 完全取消註冊裝置,請在 FirebaseInstanceId 類別上呼叫 DeleteInstanceId 方法,以刪除實例標識碼。 例如:

FirebaseInstanceId.Instance.DeleteInstanceId();

這個方法呼叫會刪除實例標識碼及其相關聯的數據。 因此,FCM 數據的定期傳送會停止。

疑難排解

下列說明搭配 Xamarin.Android 使用 Firebase 雲端通訊時可能發生的問題和因應措施。

FirebaseApp 未初始化

在某些情況下,您可能會看到此錯誤訊息:

Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.

這是一個已知問題,您可以藉由清除方案並重建專案來解決問題(建 > 置清除方案建 > 置重建方案)。

摘要

本逐步解說詳細說明在 Xamarin.Android 應用程式中實作 Firebase 雲端通訊遠端通知的步驟。 它描述如何安裝 FCM 通訊所需的必要套件,並說明如何設定 Android 指令清單以存取 FCM 伺服器。 它提供了範例程式代碼,說明如何檢查Google Play服務是否存在。 它示範如何實作與 FCM 交涉註冊令牌的實例識別碼接聽程式服務,並說明此程式代碼在應用程式背景時如何建立背景通知。 它說明如何訂閱主題訊息,並提供訊息接聽程式服務的範例實作,此服務可用來在應用程式在前景執行時接收和顯示遠端通知。