FCM — Firebase web 推播踩坑筆記

Gene Pan
8 min readOct 4, 2018

--

這篇文章是記錄自己在接 FCM 的過程,以及一些感嘆怎麼不早點發現的重點提要和 issue,我要唱一首我把我的青春給你

準備 Firebase 專案

  1. 到 Firebase 新增專案

2. 進入專案設定

3. 點「網路應用程式」

4. 將程式碼複製起來貼到你的 index.html,初始化的程式碼要記得放在 <script>的最前面

初始化

initializeApp() 後,就可以開始使用 messaging(),首先要透過 requestPermission()取得用戶同意、同意時再getToken() 向 Firebase 取 token :

成功取得 token 就可以把它打給後端保存起來。

推播小知識前情提要

其實花最多時間的是看官方文件,以及在文件不同 topic 跳來跳去找名詞定義和使用情況…

前景推播 vs 背景推播

當用戶開著你的網站,並且當前分頁也要在你的網站時會觸發前景推播(Foregorund),若用戶沒有打開網站,或者打開網站但不在當前分頁,這時會觸發背景推播(background)。

根據 Firebase 官方文件,前景推播使用 onMessage 接,背景推播我們可以直接交給 Firebase SDK 去顯示,如果要額外處理邏輯,可以使用 setBackgroundMessageHandler()

官方文件上 Foreground 和 Background 的比較

message types

FCM 給前端的推播物件(下面範例中的 payload)中包含兩個重要的 key ,官方給了它們稱呼叫 message type,分別是 data 及 notification。FCM 在兩種 message 的使用上做了區隔。

notification 是 FCM 預先定義好的 key-value,包含了通知上用戶可見(user-visible)的資訊像是 title、body、icon 等等,notification 會自動被 Firebase SDK 拿去顯示通知。

data 則是代表剩下用戶在通知上看不到的資料,用意是可以被前端拿去做更多邏輯處理。

官方文件的這段話總結了一切
FCM 傳過來的 payload 長這樣子

這兩種 message 在用法上的差別是:如果要讓 FCM 幫你自動根據 payload 顯示推播就使用 notification,如果想在前端做額外的邏輯處理可以使用 data。有興趣可以參考官方說明的 message types

接前景推播

上面已經提到可以使用 onMessage() 處理前景推播,本文的範例中是使用 new Notification() 去接要呈現的通知,並且設定通知 onclick 後要打開一個新分頁。

如果跟著做到這裡或開發到一半發現 console 裡面出現了一些奇怪的 error,可以參考下面的 issue 解法,如果沒有的話恭喜你可以跳過他們~

Issue 1:unsupported browser

在使用 firebase.messaging() 時可能會碰到上面的錯誤,這代表:

  1. 你用的瀏覽器不支援 push API。

因為 FCM 的功能是建立在 service worker 上,記得使用 Chrome、Firefox 及 Edge,值得一提的是,Android 上的 Chrome 是可以運行的,iOS 的 Chrome 則不支援。

2. 你的網站不支援 HTTPS

Firebase 推播是以 service worker 為基礎,開發必須注意 push API 和 HTTPS

Issue 2:failed service worker registration

出現這個錯誤時須透過 service worker 解決(記得先檢查是不是使用支援 push API 的瀏覽器以及有網站 HTTPS),可以嘗試下面解法:

  1. 快速解法:在根目錄建立一個空檔案 firebase-messaging-sw.js
  2. 較彈性的解法:自訂一個 service worker,在這裏姑且稱它叫 service-worker.js
自定義的 service worker

service-worker.js 一樣要引入 firebase 的 SDK 和初始化 app,此外還可以加入 setBackgroundMessageHandler() 去處理背景推播。

接下來到 index.html 中的 <script> 把 service-worker.js 註冊到瀏覽器上:

背景推播

如果要使用背景推播必須透過 service worker,懶人如我不想自己客製,所以直接在根目錄加上 firebase-messaging-sw.js 的空檔案即可,這麼做代表你會讓 firebase SDK 自動幫你拿後端給的 notification message 處理好推播

認真魔人們想要自訂 service worker 也是沒問題的,根據上面的 issue 2 ,我稱這隻檔案叫 service-worker.js(記得引入 SDK),隨後可以使用setBackgroundMessageHandler() 處理背景邏輯:

透過自訂 service work 可以客製通知要呈現的文字、圖示等等

值得注意的是,如果後端 payload 中已經有傳 notification message,firebase SDK 會取代掉 setBackgroundMessageHandler() 的邏輯、自動產生一個通知喔!當初實測好多遍發現通知怎麼都不照著自己要的文字呈現,仔細看了文件才發現這段:

FCM can send a notification message including an optional data payload. In such cases, FCM handles displaying the notification payload, and the client app handles the data payload.

真是相見恨晚。

補充

使用 curl 發推播

開發時可以使用官方提供的 curl 快速觸發推播:

curl -X POST -H "Authorization: key=你的伺服器金鑰" -H "Content-Type: application/json" -d '{
"notification": {
"title": "this is a title",
"body": "this is body"
},
"to": "你的 token"
}' "https://fcm.googleapis.com/fcm/send"

伺服器金鑰可以在「專案設定」->「Cloud messaging」中找到:

這篇是我第一篇文章,其實只是想記錄一下對學習 Firebase 推播這個心很累的過程,如果文中有不清楚或困惑的地方還請大大們告知。

參考資料

Firebase Cloud Messaging document

Firebase Github: quickstart-js

Firebase 開發筆記 — FCM 與 Web app debug

推播通知 Push Notification

簡單實作 Web 推送 — Web Push Notification by Firebase.

--

--