# FirebaseAdmin SDK For .NET - FCM篇 ###### *透過FCM 對行動裝置發送推播通知吧!* ### 前言: > *Q: Firebase Admin SDK是什麼?* Admin SDK是一組服務器庫,可以從特權環境與Firebase 進行交互,以執行以下操作: * 以完整管理員權限讀寫Realtime Database 數據。 * 使用簡單的替代方法以編程方式將Firebase Cloud Messaging 消息發送至Firebase Cloud Messaging 服務器協議。 * 生成並驗證Firebase 身份驗證令牌。 * 訪問Google Cloud 資源,例如與Firebase 項目相關聯的Cloud Storage 和Cloud Firestore 資料庫。 * 創建自己的簡化管理控制台,以執行用戶數據查詢或更改用戶的身份驗證電子郵件地址等操作。 > *本篇文章將著重在Firebase Cloud Messaging(FCM) 服務* Firebase Cloud Messaging (FCM) (FCM) 是一種跨平台消息傳遞解決方案,可以通知客戶端應用有新的電子郵件,或其他數據有待同步; 透過發送通知消息進行用戶再互動,一條消息可將最多4000 字節的載荷傳送至客戶端應用。 --- ### **開發環境與安裝** ##### 開發環境: >  Admin .NET SDK - .NET Framework 4.6.1+ 或適用於.Net Core 2.0+ 的.NET Standard 2.0 ##### FirebaseAdmin For .NET 安裝方法 > 1. 使用 .NET CLI > `dotnet add package FirebaseAdmin - version 2.3.0` > 2. 使用 套件管理器控制台 > `NuGet\Install-Package FirebaseAdmin -Version 2.3.0` *如需對服務帳號進行身份驗證並授予其訪問Firebase 服務的權限,必須生成JSON 格式的私鑰文件* ##### 生成私鑰文件 在 [Firebase控制台](https://console.firebase.google.com/)中,選擇專案>打開設置>服務帳號。點擊生成新的私鑰,然後點擊生成密鑰進行確認。 ![](https://i.imgur.com/yvrODvP.jpg) 產出的Json 文件格式會看起來像是: > ex: serviceAccountKey.json ```json= { "type": "service_account", "project_id": "專案id", "private_key_id": "私鑰id", "private_key": "-----BEGIN PRIVATE KEY-----\私鑰本人\n-----END PRIVATE KEY-----\n", "client_email": "Email", "client_id": "客戶端id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-blablabla-android.iam.gserviceaccount.com" } ``` ### **開始使用** ##### 初始化Firebase服務 在Constructure 中初始化Firebase 並產生出憑證, 缺少這一步可能會導致在傳送資料至Firebase 服務器時報錯 >  NotifyService.cs ```csharp= // NotifyService Constructure public NotifyService(IServiceProvider provider) : base(provider) { // 當找不到firebase實體時,重新初始化產出憑證 if (FirebaseApp.DefaultInstance == null) { FirebaseApp.Create(new AppOptions() { Credential = GoogleCredential.FromFile("path/to/serviceAccountKey.json"), }); } } ``` 無論是哪個平台,所有應用實例都可以解讀以下通用字段: * message.notification.title * message.notification.body * message.data ##### 向單一特定裝置發送通知 ```csharp= /// <summary> /// 向單一特定裝置發送通知 /// </summary> /// <param name="notifyToken">已驗證的Notify Token</param> /// <returns></returns> public async Task SendNotify(string notifyToken) { var message = new Message() { Notification = new Notification() { Title = "推播測試", Body = "通用平台之單一裝置推播測試" }, Token = notifyToken }; // 向該裝置發送推播 string response = await FirebaseMessaging.DefaultInstance.SendAsync(message); Console.WriteLine("發送推播成功: " + response); } ``` 註解: > "Message" 是 Firebase Cloud Messaging (FCM) 中用於發送通知的一個類別,它包含了各種用於定義推播訊息內容的屬性。 > "Notification"是指在行動裝置的訊息列(notification drawer)中顯示的訊息。程式碼中的 Notification()是一個 C# 物件,用於設定要發送的通知的標題和內容。 ##### **使用針對具體平台的字段** 使用時機 * 僅向特定平台發送字段 * 發送通用字段以及針對具體平台的字段 > 如果僅希望向特定平台發送值時,"不要"使用通用字段,而應使用針對具體平台的字段。 > 例如,如需僅向Apple 平台和Web 發送通知,而不向Android 發送通知,必須針對Apple 和Web 各使用一組字段 ex: 個別向安卓與IOS發送不同的推播設定 > NotifyService.cs ```csharp= /// <summary> /// 分別向Android與IOS發送不同設定的推播 /// </summary> /// <param name="notifyToken"></param> /// <returns></returns> public async Task SendNotify2(string notifyToken) { var message = new Message { Notification = new Notification() { Title = "推播測試", Body = "依照設備推播不同的設定", }, // 為Android目標設備設定樣式或是時間...等等 Android = new AndroidConfig() { TimeToLive = TimeSpan.FromHours(1), Notification = new AndroidNotification() { Icon = "stock_ticker_update", Color = "#f45342", }, }, // 為IOS目標設備設定應用程序圖標右上角的紅色圓形數字提醒 Apns = new ApnsConfig() { Aps = new Aps() { Badge = 42, }, } }; // 向設備發送推播 string response = await FirebaseMessaging.DefaultInstance.SendAsync(message2); Console.WriteLine("發送推播成功: " + response); } ``` 註解: > Badge Notification是指出現在App圖標右上角的紅色圓形數字提醒,用於提醒一些無需即時處理的消息,比如程序更新數、未讀郵件數等。 > 向多台裝置發送消息![](https://i.imgur.com/jsisbPP.jpg) ##### 發送訊息給多個裝置 ***將消息推播到多個裝置。每次調用時,最多可以指定"500個" 裝置註冊令牌*** ex: 向多個裝置發送訊息 > NotifyService.cs ```csharp = /// <summary> /// 向多個裝置發送推播 /// </summary> /// <returns></returns> public async Task SendNotifyToMultiDevice() { // These registration tokens come from the client FCM SDKs. var registrationTokens = new List<string>() { "TOKEN_1", "TOKEN_2", // ... //一個 Batch最多有500筆Token "TOKEN_500", }; var message = new MulticastMessage() { Tokens = registrationTokens, Data = new Dictionary<string, string>() { { "platform", "通用平台" }, { "object", "多個裝置" } }, }; var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(message); //檢查發送失敗的Token if (response.FailureCount > 0) { var failedTokens = new List<string>(); for (var i = 0; i < response.Responses.Count; i++) { if (!response.Responses[i].IsSuccess) { //將失敗的Token加入至List裡 failedTokens.Add(registrationTokens[i]); } } Console.WriteLine($"失敗的Token List: {failedTokens}"); } } ``` ##### **Data 和 CustomData 的區別** 在 FCM 中,Data 和 CustomData 都是用來傳遞自訂資料的機制,但它們在傳遞資料的方式上有些微的差別 1. *Data*:是 FCM 的一個內建的機制,用來傳遞 key-value pair 的資料。當手機端收到訊息時,這些資料會透過 Intent 傳遞給應用程式。 1. *CustomData*:顧名思義,就是使用者自行定義的資料,可以是任何格式的資料,例如 JSON、XML 等等。CustomData 是透過傳送 payload 的方式,讓 FCM 將資料原封不動地轉發給設備端應用程式。 ex: 向多個IOS裝置發送訊息 > NotifyService.cs ```csharp= /// <summary> /// 向多個IOS裝置發送推播 /// </summary> /// <param name="tokenList">IOS裝置Token List</param> /// <returns></returns> public async Task SendNotifyToMultiIOS(List<string> tokenList) { var message = new MulticastMessage() { Tokens = tokenList, Apns = new ApnsConfig() { Aps = new Aps() { Alert = new ApsAlert() { Title = "FirebaseAdmin SDK For .NET", Body = "本篇文章透過Firebase 服務中的FCM 實作對行動裝置發送推播通知" }, Badge = 1, Sound = "default" }, CustomData = new Dictionary<string, object>() { { "platform", "IOS" }, { "devices", "多個裝置" } } } }; await FirebaseMessaging.DefaultInstance.SendMulticastAsync(message); } ``` --- ### 結論 透過FCM 我們可以對裝置發送推播訊息,也可以針對不同的裝置發送不同格式的Notify,Firebase Admin不只是提供了Clound Messaging,還有Authentication ,Real Time的資料庫,Analytics 提供事件報告幫助了解用戶與應用進行互動,還有許多與Google相關的功能。 未來有機會再跟大家介紹 ❤️❤️