Firebase 推播服務(Firebase Cloud Messaging FCM)

法蘭克的 iOS 世界
16 min readApr 20, 2017

--

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 的推播流程圖。

透過 Firebase 後台或 Firebase 的 SDK 推送訊息,並藉由 Firebase Colud Messageing 的服務推送到各種平台上

前置作業:

  1. 必須擁有 Apple 開發者帳號。
  2. 必須擁有可以測試的實體裝置,例如 iPhone、iPad 等等。
  3. 建立一個空的專案,並把 Bundle ID 記下來因後續會使用的到。

實作流程

  1. 使用 cocoaPods 載入 Firebase Cloud Message SDK 至 Xcode 中。
  2. 使用 Google 帳號登入 Firebase 後台並建立專案。
  3. 從 Mac 的 key chain 匯出 .certSigningRequest (CSR) 檔案。
  4. 登入 Apple 開發者後台建立含有遠程通知服務的 App IDs。
  5. 配置 App IDs 遠程通知的設定。
  6. 在 Apple 開發者後台註冊接收遠程通知的設備(僅測試環境需要設定)。
  7. 在 Apple 開發者後台配置 Provisioning Profiles(僅測試環境需要設定)。
  8. 在 Firebase 後台專案底下匯入步驟 7 所產生的憑證(.p12檔)。
  9. 撰寫接收遠程通知的程式碼,並修改接收到通知訊息時的動作別(分成 Swift3 和 Swift4 版本)。
  10. 至 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 推播的格式

以上這張圖就是用 Postman 推播的格式,這個動作跟從 Firebase 後台推播的動作其實是一樣的,以下就分別說明上圖的各欄位所代表的意義為何。

post url => 固定的 url,也就是 Firebase 推播的 Server。

registration_ids => Firebase Token。

data => 該 key 值下的物件可以放客製化的欄位,這邊法蘭克放了一個 planId,主要是要用來識別,如果該欄位不為空的話,使用者點擊推播訊息的時侯要進到特定的頁面。

notification => 顯示在使用者手機上的推播 Title 和 Body。

接下來要演示如何在 App 端取得 Data 的資料,而我會在使用者點擊推播訊息所會觸發的 userNotificationCenter(_:didReceive:withCompletionHandler:) delegate 裡來取得由 postman 送出的資料。

在 userNotificationCenter(_:didReceive:withCompletionHandler:) 裡加入此段邏輯

第 2 行 => 印出由 postman 送出的整包資料。

第 3 行 => 取出 data 裡的資料,這裡比較特別的是資料型態為 AnyHashable。

第 4 行 => console 如下圖所示,如果是 AnyHashable 型態的資料,要用第 3 行演示的方法取出。

console 呈現由 postman 送出的資料

結論

  • 該範例的環境是在 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」讓我持續提供好文章給您。

--

--