Firebase 推播服務(Firebase Cloud Messaging FCM)
Firebase Cloud Messaging(FCM) 是 Goolge 在 2016 併購 Firebase 後所發表的服務之一,而早期 Google 的自有的推播服務則叫做 Google Cloud Messaging(GCM),相對於 GCM 而 FCM 最大的進步是能在網頁上的主控台推送通知至各種平台中,而這邊我們所要注意的 FCM 是無法針對單一平台做推送的。在之前法蘭克也曾經實作過 Apple Notification,它的設定流程相對於 FCM 來得複雜許多且無法跨平台,而這就是我們為什麼要使用 FCM 來實作推播的理由了。
而為什麼我會說 FCM 相對於 Apple Notification 設定較容易,因為 FCM 在 Apple 的 APNs 中間夾了一層介面(interface) 來簡化在實作 Apple Notification 時所必須在後台設定的一大堆繁鎖的動作,but…這並不代表完全不需在 Apple 後台做設定 ,還是得在 Apple 後台產出憑證並上傳至 Firebase,這在教學中會提到!另外 FCM 可直接從後台推送訊息至雙平台的裝置,而 Apple Notification 不用說相信大家也知道,只能推送到 iPhone 裝置,也就是說貴司的 App 如果有雙平台的話,就要請 Android 的工程師再另外設置,站在公司的角度這是很耗費成本的,如果透過 FCM 是不需要這麼做的。以下就讓我們就來看看 FCM 的推播流程圖。
前置作業:
- 必須擁有 Apple 開發者帳號。
- 必須擁有可以測試的實體裝置,例如 iPhone、iPad 等等。
- 建立一個空的專案,並把 Bundle ID 記下來因後續會使用的到。
實作流程
- 使用 cocoaPods 載入 Firebase Cloud Message SDK 至 Xcode 中。
- 使用 Google 帳號登入 Firebase 後台並建立專案。
- 從 Mac 的 key chain 匯出 .certSigningRequest (CSR) 檔案。
- 登入 Apple 開發者後台建立含有遠程通知服務的 App IDs。
- 配置 App IDs 遠程通知的設定。
- 在 Apple 開發者後台註冊接收遠程通知的設備(僅測試環境需要設定)。
- 在 Apple 開發者後台配置 Provisioning Profiles(僅測試環境需要設定)。
- 在 Firebase 後台專案底下匯入步驟 7 所產生的憑證(.p12檔)。
- 撰寫接收遠程通知的程式碼,並修改接收到通知訊息時的動作別(分成 Swift3 和 Swift4 版本)。
- 至 Firebase 後台的 Notification 測試推播。
1. 使用 cocoaPods 載入 Google Cloud Message SDK 至 Xcode 中
2. 使用 Google 帳號登入 Firebase 後台並建立專案
2.1 新增專案
2.2 建立專案
專案名稱:自行命名即可
2.3 將 Firebase 加入 iOS 的應用程式
iOS 繫結 ID => 前置作業第 3 項的 Bundle ID
2.4 下載 GoogleService-Info.plist 後點選「繼續」直到完成所有步驟
2.5 將 GoogleService-Info.plist 拖曳至 Xcode 專案裡
3. 從 key chain 匯出 .certSigningRequest (CSR) 檔案
CSR 在後面配置 App IDs 遠程通知時會須用到。
3.1 打開 Launchpad 搜尋 key chain
3.2 選擇 左上鑰匙圈存取 → 憑證輔助程式 → 從憑證授權要求憑證
3.3 填入相關資訊後匯出 CSR
- 使用者電子郵件位址:Apple ID 的 email
- 一般名稱:英文名字
- 已將要求:儲存到磁碟
備註:該 CSR 檔案後續會用到,請妥善保存。
4. 登入開發者後台創建含有遠程通知服務的 App IDs
4.1 登入後台的 Certificates, Identifiers & Profiles
4.2 在左列的選單選擇 App IDs 並點選「+」
4.3 註冊 App ID
- Name :任意填入即可
- Bundle ID:填入前置作業第 3 項所產生的 Bundle ID
Enable Service :勾選 Push Notification
4.4 點擊下一步至完成設定
這邊會看到 Push Notification = Configurable 代表還沒設定完,暫且先點選 Done,等等再繼續設定。
5. 配置 App IDs 遠程通知的設定
5.1 點擊剛剛產生的 GoogleCloudMessage App ID 展開後,點選 Edit
5.2 往下滾找到產生測試時期通知的 SSL 證書(Development SSL Certificate),點擊 Create Certificate
5.3 滾到最下面點擊 Continue 開始上傳步驟 3 所產生的 CertificateSigningRequest.certSigningRequest(CSR) 檔案
5.4 下載 .cer 檔案
5.5 點擊兩下 .cer 檔案執行安裝到本機
5.6 確認有無安裝至 key chain
點擊兩下 .cer 會自動安裝,待安裝完後會自動打開 key chain,這時請檢查 .cer 是否已安裝。若沒有自動打開 key chain,則可依步驟 1 的方式查看。
6. 在 Apple 開發者後台註冊接收遠程通知的設備(僅測試環境需要設定)
先至後台確認測試的設備有無註冊過,若沒有才要執行註冊的動作,下圖表示已註冊過即可略過該第 6 大步驟。
備註:通常如果被測試機之前如果有連接 Xcode 安裝測試 App 的話,這個步驟要做的事情就都會貼心的幫我們做好了。
6.1 開啟 Xcode 選擇 Window → Devices
6.2 複製 XXX 的 iPhond 的 Identifier
6.3 至開發者後台的 Devices 選單註冊該設備
7. 在 Apple 開發者後台配置 Provisioning Profiles(僅測試環境需要設定)
7.1 在 Apple 開發者後台選取左側選單點擊 Provisioning Profiles下的 Development(開發時期測試用),並點選「+」號
7.2 選取 iOS App Development 後點選 Continue
7.3 選擇剛剛創建的 App ID 後點選 Continue
7.4 選擇 iOS 開發者證書,若不確認是哪一個的話,全部勾選亦可
7.5 選擇測試的設備
7.6 替 Profile 命名(任意即可,因只是測試用的)
7.7 下載 GoogleCloudMessageDemo.mobileprovision 檔並點擊兩下執行安裝
8. 在 Firebase 後台專案底下匯入步驟 7 所產生的憑證(.p12檔)
8.1 打開 launchpad 搜尋 key chain
8.2 點選左側選單憑證 → 步驟 7.7 所安裝的憑證檔 → 右鍵 → 輸出balala…
8.3 確認檔案格式為 .p12 即可儲存
8.4 點選儲存後系統會詢問是否輸入密碼來保護該檔案,可以直接選擇好來跳過該提示,也可自行輸入密碼來保護,但請牢記該密碼,因在上傳到 Firebase 時會用到。
8.5 登入 Firebase 後台將匯出的 .p12 檔上傳,請使用 Safari 10(含)以上的版本或 Chrome 開啟,否則會看不到該功能。
Overview 旁的齒輪 → 專案設定 → Cloud Message → 上傳憑證 → 選擇步驟 8.4 產出的 .p12 檔
以上已完成所有的設定了,再來要在 Xcode 裡加入 Firebase 所提供的 Quickstart 專案裡的程式碼了。
9. 撰寫接收遠程通知的程式碼,並修改接收到通知訊息時的動作別(分成 Swift3 和 Swift4 版本)
Swift3
- Xcode 版本(8.0)
- Firebase/Messaging (4.0.1)
用以下程式碼覆蓋掉整個 AppDelegate.swift
第 43~46 行 => 設定觀察者去監聽 Token 的變化。
第 82~89 行 => 當取到 Token 時所會觸發的事件。
第 142~157 行 => 在前景收到推播時會觸發的 delegate。而第 156 行則是定義在收到通知時要如何呈現的動作,務必將其改成 .alert,否則在 iOS10 的 Device 上是不會有任何動作的。
第 159~173 行 => App 在關掉的狀態下或 App 在背景或前景的狀態下,點擊推播訊息時所會觸發的 delegate。
在 ViewController.swift 加入取得 token 的程式碼,這邊不影響接收通知的動作,只是單純要取得 Device 的 token而己。
第 5~9 行 => 主動的去跟 Firebase 要 Device Token。
Swift4
- Xcode 版本(9.3)
- Firebase/Messaging (5.0.1)
用以下程式碼覆蓋掉整個 AppDelegate.swift
第 18~45 行 => 與 Swift3 的寫法大同小異。
第 69~92 行 => iOS10 以下的版本接收推播訊息的 delegate,又分為從後台推送出觸發的 delegate 和點擊推播訊息所觸發的 delegate,如果要將後台推播的訊息另存起來,該 delegate 就會派上用場了。
第 103~117 行 => 取得 DeviceToken,通常是給後台人員利用各種語言來推播時用的 Token,在實務上通常在收到該 Token 會將它送到後台並且和帳號綁定在一起,以利後續針對單一帳號推播使用。以上是被動的接收 Token。而有些時侯我們得必須主動的去跟 Firebase 要 Devie Token 的,語法如下:
InstanceID.instanceID().token() // 主動去跟 Firebase 要 Device Token
第 119~152 行 => iOS10 以上的版本接收推播訊息的 delegate,又分為從後台推送出觸發的 delegate 和點擊推播訊息所觸發的 delegate,如果要將後台推播的訊息另存起來,該 delegate 就會派上用場了。
第 156~165 行 => iOS10 以上用來接收 firebase token 的 delegate,該 token 可用來從 firebase 後台推送單一裝置時使用。
以上不管用 Swift3 或 Swift4 最後都得打開 Xcode Push Notification 的選項
選擇專案 → TARGETS → Capabilities → ON
10. 至 Firebase 後台的 Notification 測試推播
10.1 將 App 安裝至手機上並執行,查看 console 是否有成功連線至 FCM(for 使用 Swift3 語法撰寫推播才有得情境,若是使用 Swift4 則直接跳到 步驟10.2)
10.2 登入 Firebase 後台選擇左測選單 Notification
訊息文字 => 通知的內容
應用程式 => 選擇專案
補充說明
- 有時侯推播的內容除了顯示在 App 端的畫面上讓使用者可以看的到的 Title 和 Body 外,如果我們還要額外增加其它的客製化資料,這可以辦得到嗎?答案是可以的,法蘭克就用 Postman 來演示這個案例。
以上這張圖就是用 Postman 推播的格式,這個動作跟從 Firebase 後台推播的動作其實是一樣的,以下就分別說明上圖的各欄位所代表的意義為何。
post url => 固定的 url,也就是 Firebase 推播的 Server。
registration_ids => Firebase Token。
data => 該 key 值下的物件可以放客製化的欄位,這邊法蘭克放了一個 planId,主要是要用來識別,如果該欄位不為空的話,使用者點擊推播訊息的時侯要進到特定的頁面。
notification => 顯示在使用者手機上的推播 Title 和 Body。
接下來要演示如何在 App 端取得 Data 的資料,而我會在使用者點擊推播訊息所會觸發的 userNotificationCenter(_:didReceive:withCompletionHandler:) delegate 裡來取得由 postman 送出的資料。
第 2 行 => 印出由 postman 送出的整包資料。
第 3 行 => 取出 data 裡的資料,這裡比較特別的是資料型態為 AnyHashable。
第 4 行 => console 如下圖所示,如果是 AnyHashable 型態的資料,要用第 3 行演示的方法取出。
結論
- 該範例的環境是在 Development 所演示的,若是 App 是透過 TestFlight 或者是上架到正式區,請務必記得將 Firebase 上的 .p12 置換成 Production SSL Certificate,如果不想用置換的方式,Firebase 上也可並存 Development 和 Production 的憑證,從下圖中上傳並下載,最後從 keychain 匯出(可參考第 5 點和第 8 點 )。
- Firebase Token 是用來從 Firebase 後台推送單一裝置用;而 Device Token 通常是給後台人員利用各種語言來推播時用的 Token,在實務上通常在收到該 Token 會將它送到後台並且和帳號綁定在一起,以利後續針對單一帳號推播使用。
- Device Token 除了可以被動的接收外,我們也可以主動的去取得。因為在特定的情境下就得必須這麼做,例如:App 有登入 + 推播的機制下,我們就常常需要將帳號和 Device Token 綁定在一起。此時如果 application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 沒有取得 Token,我們就得主動的去取得 Device Token。
如果您喜歡我的文章,請多按幾下「拍手」給我鼓勵,或是按「follow」讓我持續提供好文章給您。