2017年10月17日 星期二

Firebase 開發筆記 - Firebase Cloud Messaging (FCM) 初體驗、 Topic 管理與 Web notification

firebase-web-console

最近強者同事推薦使用 FCM ,看了一下,對於計費方式有點抖,若一切免費的話,真的超佛心 :P 由於支援潮流的訊息訂閱架構,基本上幾乎可以不用自行紀錄 notification token 了,用起來很直觀又方便。例如,想要個別通知時,可以每一個 user 給予一個 topic id (如 user id) ,就能夠不用紀錄 raw notification token 單獨發訊給對方!有一點點像用運算取代空間感。

當發送 push 給使用者後,且使用者取得訊息時,關注 Realtime db 的 Download 流量有變動,不知是不是真的要計算流量?若是的話,大約發送一則訊息算 2KB ,而免費版流量 10GB/month,約一個月可以發送 500萬則訊息。

firebase-rt-db-download

若真的要計算流量費的話,那 FCM 就不是免錢,接著要花錢則是 25 美金方案有 20GB/month ,接著更高級則是 $1/GB 計費。

Updated @ 2017/10/18: 與 Firebase 客服聯繫,確認 FCM 不佔用 Realtime Database 流量!並且一口氣發送 100 則後,流量也沒有大量增加,符合預期!超佛心。強者同事提醒,對於 Database Download 流量,可能是 Firebase dashboard/console 的資訊讀寫 ( https://firebase.google.com/docs/database/usage/billing - Firebase console data )

聊聊趣味的地方,關於 Topic 管理機制,當你有 FCM token 後,可以在 server site 幫 device 訂閱 topic 喔!這功能很便利,就像...你紀錄了一堆 GCM token / APNs token 後,自己過濾對象,再進行發送。然而,topic 概念在於"使用情境"知道後,直接刻在 app 端,只是突然新增使用情境時,就得變成新版 app user 可以接受,舊版則無法接受到訊息,這時 server site 若有記錄 FCM token 時,就可以代勞幫忙訂閱:

https://developers.google.com/instance-id/reference/server#manage_relationship_maps_for_multiple_app_instances

https://iid.googleapis.com/iid/v1:batchAdd
Content-Type:application/json
Authorization:key=API_KEY
{
   "to": "/topics/movies",
   "registration_tokens": ["nKctODamlM4:CKrh_PC8kIb7O...", "1uoasi24:9jsjwuw...", "798aywu:cba420..."],
}


同理,也可以取消訂閱:https://iid.googleapis.com/iid/v1:batchRemove

若 server site 是 node.js 的,可以直接用 SDK :https://firebase.google.com/docs/cloud-messaging/admin/manage-topic-subscriptions

最後,筆記一下 Web app 的部分:假設網站服務位置為 https://example.com/fcm/ ,預設都要在根目錄埋上 firebase-messaging-sw.js 檔案,可以空白。

$ touch /var/www/firebase-messaging-sw.js
$ vim /var/www/fcm/index.html
<html>
<head>
<script src="https://www.gstatic.com/firebasejs/4.5.2/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "your-app-apikey",
authDomain: "your-app.firebaseapp.com",
databaseURL: "https://your-app.firebaseio.com",
projectId: "your-app",
storageBucket: "your-app.appspot.com",
messagingSenderId: "your-app-id"
};
firebase.initializeApp(config);
</script>
</head>
<body>
<script>
const messaging = firebase.messaging();

messaging.onTokenRefresh(function() {
messaging.getToken()
.then(function(refreshedToken) {
console.log('Token refreshed.', refreshedToken);
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});

messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
});

messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
resetUI();
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});

function resetUI() {
console.log('resetUI');
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
console.log("currentToken:", currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
});
}
</script>
</body>
</html>


如此一來,用 chrome browser 瀏覽 https://example.com/fcm/ 會彈跳視窗詢問是否接收訊息,點擊接受後,在 dev tools 的 console 可以看到:

Notification permission granted.
resetUI
currentToken: thisClientFCMToken

如此一來,就可以對他發訊、設定此 client 去訂閱 topic 了:

$ curl -X POST -H "Authorization: key=YourFCMAppServerKey" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "Hello",
    "body": "World",
    "icon": "firebase-logo.png",
    "click_action": "http://localhost:8081"
  },
  "to": "thisClientFCMToken"
}' "https://fcm.googleapis.com/fcm/send"

$ curl -X POST -H "Authorization: key= YourFCMAppServerKey" -H "Content-Type: application/json" -d '{
  "registration_tokens":["thisClientFCMToken"],
  "to": "/topics/foo-bar"
}' "https://iid.googleapis.com/iid/v1:batchAdd"

$ curl -X POST -H "Authorization: key= YourFCMAppServerKey" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "Hello",
    "body": "World",
    "icon": "firebase-logo.png",
    "click_action": "http://localhost:8081"
  },
  "to": "/topics/foo-bar"
}' "https://fcm.googleapis.com/fcm/send"

沒有留言:

張貼留言