# 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/)中,選擇專案>打開設置>服務帳號。點擊生成新的私鑰,然後點擊生成密鑰進行確認。

產出的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圖標右上角的紅色圓形數字提醒,用於提醒一些無需即時處理的消息,比如程序更新數、未讀郵件數等。
> 向多台裝置發送消息
##### 發送訊息給多個裝置
***將消息推播到多個裝置。每次調用時,最多可以指定"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相關的功能。
未來有機會再跟大家介紹 ❤️❤️