2016年10月10日 星期一

Android: 利用Firebase實作使用者間的產品分享機制

前言

Firebase是一個即時的雲端資料庫,原本是一間提供雲端服務的公司,主要供開發人員快速建立網頁與行動裝置,後來被Google收購後,整合了許多新的功能與SDK,像是Analytics, Auth, Storage, Hosting, Test Lab, Crash Reporting, Notifications, Remote Config, Dynamic Links與AdMob等服務。這些服務可以供行動開發者無須依賴後台開發人員的人力,而且這個資料庫也有別於關聯式資料庫,是以Json為資料結構的資料庫,自己便能輕鬆實作出仰賴資料庫的應用程式,也可以看看影片瞭解更多關於Firebase的介紹,在本篇不多著墨,若是對於上述的服務有更大的興趣,更可以利用Firebase Help Center來協助您。而在這個實作中,我們會利用Firebase的Realtime Database, Remote Config與Notifications。

言歸正傳,由於本人目前在電商公司服務,都是開發與電商有關的應用程式,有些想法想記錄下來,於是,今天想利用Firebase的即時資料庫,來做個簡單使用者間的商品分享。咦!提到這裡,其實很多手機應用程式都有分享的功能,我何必在自己的應用程式加入?在分享的功能中,往往都是透過選擇器使用第三方的應用程式來分享,像是Line, Facebook, Email...等等,但我覺得這個有點不太方便,加上使用者也必須跳離我們的應用程式才能得知這些訊息,假如能讓安裝我們應用程式的使用者加入其他會員,讓使用者選擇欲分享產品的對象,這樣除了可以讓使用者無須借助第三方應用程式,接收方也能及時得知推薦商品的資訊。廢話太多,我們就開始著手利用Firebase來實作使用者間的商品分享功能吧!以下是實作的主要概念與實作方式。

雛形(Prototype)





實作細節

  • 註冊Firebase/Google帳號
    • 首先我們需要一個Google帳號,這個帳號將來可以讓你進行後台管理與設定,但是大家應該都有Google帳號,所以這個部分就不多做說明。若沒有帳號的人,請至Google網頁申請。
  • 開啟Android新專案
    • 透過Android Studio建立一個名為Product-Sharing-Notification新專案,如下圖。

    • 選擇開發平台與SDK,如下圖。

    • 加入Activity,如下圖。

  • 加入Firebase libs
    • 當專案建立好後,我們需要讓專案與Firebase相連結。點選Android Studio工具列的Tools -> Firebase,如下圖。

    • 此時Android Studio會出現Firebase的側邊選單,裡面會列出Firebase提供的服務,我們可先選擇Realtime Database -> Save and retrieve data -> Connect your app to Firebase,如下圖。

    • 這時候你也能透過瀏覽器登入Firebase帳號,進入後台檢查是否專案建置成功,成功則會有個與你於Android Studio建置相同的專案名稱,如下圖。

    • 此時我們點選Connect your app to Firebase的按鈕,如下圖。

    • 若沒有直接在Firebase後台建立資料庫,可以直接透過Create new Firebase project的選項,由Android Studio為你建立,如果你已經在後台建置過,也可以透過Choose an existing Firebase or Google project的選項連結,如下圖。

    • 連結成功後,Connect to Firebase的按鈕則會變成綠燈,顯示Connected,如下圖。

    • 接下來點選Add the Realtime Database to your app按鈕,這部分是將Google services的服務與Firebase database lib加入Gradle內,可以透過自動建置,也能自行在Gradle加入,如下圖。


    • 加入成功後,也同樣會變成綠燈,顯示Connected,如下圖。

    • 除了Realtime Database的服務,我們也會利用Cloud Messaging(FCM)和的服務來完成需求,所以可以利用同樣方式,將這個服務加入至Gradle中,如下圖。

    • 如果你順利與Firebase後台連接成功,Project中也會多了一個google-services.json的檔案,這個檔案則是記錄了你的專案與Firebase所需的相關資料,若沒有這個檔案,也可以在Firebase下載,如下圖。

  • 其他Lib的準備
    • 這邊可以視平常開發的習慣,選擇你需使用的Lib。這邊我會利用到網路存取、Json剖析以及圖片存取的服務,所以加入了以下Lib至Gradle,如下圖。
      • 網路存取: Volley
      • 圖片存取: Glide和Picasso
      • Jason剖析: Gson

  • 介面呈現
    • 前置作業準備好了,可以開始按照Prototype來刻我們的Layout。我們需要註冊一個會員ID,來識別每個會員,同時也需要傳送一個會員ID作為分享的對象,以下是Android實際的Layout,如下圖。

  • 實作ID註冊
    • 接下來就可以串接程式了,先完成註冊的功能,讓Firebase資料庫可以儲存會員ID的資料,以及其他所需的資料。
    • Firebase的後台要發送訊息,是如何識別每支手機?在過去實作GCM時,當你註冊GCM的同時,會獲得一個Device Token,Firebase也須做相同的事達到同樣目的,所以我們需要利用FirebaseInstanceId的類別取得相對應的Token,其使用方式為FirebaseInstanceId.getInstance().getToken()。
    • 這個Token並不是永久相同的,當你把應用程式移除並重新安裝後,Token同時會更新,這時我們要在更新時取得最新的Token,並將它儲存起來,你可以使用Preference或是其他方式儲存。如何得知Token已經更新?我們需要繼承FirebaseInstanceIdService這個類別,並且覆寫onTokenRefresh()方法,這個方法會在Token更新時,進行回呼,這時你就可以取得最新的Token資料,並將它儲存,如下圖。

    • 實作完成後,請記得在AndroidManifest中加入這個Service,如下圖。

    • 再來,資料該如何寫入Firebase?可透過Firebase提供的DatabaseReference物件存取,它是用來與Firebase資料庫做資料相關操作的服務。例如:我想要在Firebase資料庫儲存一筆會員資料,該會員資料除了會員ID外,還儲存了該手機的Token(識別碼),以及使用平台,資料結構如下圖。

  • 接下來,我們可以利用DatabaseReference.的child()方法來新增一個名為users的欄位,在users的欄位下還有一個會員Id,同樣也可以用child()來完成,如下圖。

  • 最後該在何時新增DeviceList欄位底下的資料?首先我們需建立一個記錄Device與Token的資料物件,這邊我取名為DeviceData,其結構如下圖。
  • 再透過DatabaseReference的addListenerForSingleValueEvent()方法,實作當中的onDataChange()方法,這個方法是當資料更新時,可以讓我們讀取最新的資料,這邊提供我們先做一些資料的判斷,再透過setValue()的方法將該資料結構儲存至Firebase中即可,如下圖。
  • 實作推播功能
    • 實作推播只需要幾個步驟
    • 首先,準備好要推播的內容,以這個功能來說,推播的內容有產品名稱以及訊息,接著取你想分享對象的Token,這樣推播才能知道該送給哪個裝置。
      • 該如何取得欲分享對象的Token?先前註冊的功能已經幫我們把每個會員的Token,皆已存入Firebase中,這時同樣可透過DatabaseReference取得。

      • 先前我們透過DatabaseReference的addListenerForSingleValueEvent()方法,會要求我們傳入一個ValueEventListener物件,這個物件要實作onDataChange()與onCancelled()兩個方法,當中的onDataChange()會有個DataSnapshot的物件傳入,我們便可以透過欲傳送推播對象的ID,再由該物件取得其當時註冊的Token,如下圖。
    • 準備好送出的推播格式,透過網路存取機制送出。
      • 取到傳送對象的Token後,可以準備你要推播的格式,這邊的格式需要回傳Json格式,如下圖。

    • 這個格式共有Target與Payload兩部分,Traget需要有你推播對象的Token,Payload也就是傳送的內容。至於這些內容可以詳細參考文件,客製化你所需的內容,這邊就已能達到我們目的即可,如下圖。




    • 準備好傳送格式後,我們需透過網路存取的Post方式傳送推播,需要準備Header內容,這個Header包含這個專案的金鑰(可透過Firebase查詢到)以及Content-Type,如下圖。




    • 最後則是Post的URL:https://fcm.googleapis.com/fcm/send
    • 準備好後,則可以傳送推播了。

  • 最後實作FirebaseMessagingService,透過這個服務,可取得手機接收訊息後,供你顯示資料內容。
    • 實作時,會要求覆寫onMessageReceived()方法,這邊就可以實作當你接收到訊息後,你該怎麼顯示。

    • 顯示部分則是產生Notification物件,其實跟以前的GCM沒什麼差異,其方式如下圖。

    • 記得,當你實作FirebaseMessagingService後,請記得將該Service加至AndroidManifest.xml中,如下圖。

    • 實際測試


4 則留言:

  1. 謝謝,這篇很有幫助,救了我的大學專題。根據自己需求稍加修改一下蠻好用的!
    但我想請問一下:
    我將您github上的專案,有關推播的類別直接複製到我的專案裡
    也有在gradle匯入volley、glide、gson、picasso的函式庫,並與自己的Firebase連結
    但為什麼在Android專案中,有些類別都無法識別呢?
    包括您原專案下的com.xy.network下的BaseApiManager、IApiResponseListener、JsonObjApiFactory、BaseHeaderBean,
    以及com.bumptech.glide.request.animation.GlideAnimation(但其他glide類別可以識別)。
    這些應該不是您自己建立的類別吧?

    回覆刪除
    回覆
    1. 其實還不只這些類別,com.xy.network下的類別似乎都不能識別

      刪除
  2. Hi, 仲佑
    因為有些我有另外包一份自己的實作,因為這部份視個人習慣,跟使用firebase沒太大關係。不過這篇已經很久了,firebase也更新版本,機制有些不同囉!

    回覆刪除