最近開始接觸 React Native 的專案了,能用前端技術跟知識同時開發 iOS/Android App 滿新奇的!雖然缺乏原生 App 的知識讓我踩了不少坑,其中不少還是非常低能的坑 XD!
這次實作的任務是要在 App 加上 Google/Facebook 登入的功能,而會員系統是建構在 Amazon Cognito 上面的,再加上 React Native 的相關套件 – react-native-facebook-login
及 react-native-google-signin
來實作 App 中的登入功能。其中有些設定上的眉角讓我花了不少時間嘗試,所以整理成本篇的筆記備忘囉~
本文大綱
本篇文章滿長的,所以先整理大綱在此,了解一下會介紹到的部份:
- 本文的套件版本
- AWS SDK React Native 與 Amazon Cognito
- react-native-facebook-login
- react-native-google-signin
- 繼續未完的 Amazon Cognito 設定
- 前端程式
- 疑難排解
- 用 Amazon Lambda 來做 Serverless API
- Amazon API Gateway
- 在 App 端補上註冊(register)的 function
- Source Code
- 參考資料
本文的套件版本
由於這是個升版可能就變天的世代,所以開始之前先將相關版本列於下方:
- react-native 0.44
- aws-sdk-react-native (5c9f30a21acdb0d50d3f5eee6e78b584e3419ea4)
- react-native-facebook-login 1.5.0
- react-native-google-signin 0.10.0
AWS SDK React Native 與 Amazon Cognito
首先,要建構會員系統的話,依過去的經驗,有很多部分要處理,像是寫會員註冊、忘記密碼、認證、更新資料等後端程式,還要建會員資料庫、思考怎麼跟第三方社群登入(像是本文主要目的的 Google、Facebook 登入)串接、怎麼讓桌機與手機都能 work… 等一拖拉庫的事情。雖然要一個個自己來也是可以,但像前端工程師如我,可能就要花上不少時間了,也有時間成本的考量,而 Amazon Cognito 提供了一套不錯的跨裝置會員系統解決方案。
Amazon Cognito 讓您輕鬆新增使用者註冊與登入功能到行動應用程式與 Web 應用程式。使用 Amazon Cognito,您也可以選擇透過 Facebook、Twitter 或 Amazon 等社交身分供應商、利用 SAML 身分解決方案,或使用自己的身分系統來驗證使用者。除此之外,Amazon Cognito 可讓您將資料儲存在使用者的本機裝置,這允許應用程式即使在裝置離線時也能運作。然後,您可以同步使用者不同裝置之間的資料,無論他們使用哪部裝置,都能獲得一致的應用程式體驗。
而此次的任務就是在 React Native 的架構下要導入以 Cognito 為基礎的社群會員(Google 與 Facebook)登入流程,當然也可以選用非第三方的身分認證,像是手機、E-mail 認證等方式,不過就不在本文介紹範圍中了。首先,假設我們已經設定好一個基本的 React Native 的專案了,接下來就要安裝相關的套件 – aws-sdk-react-native。
註:其實在本文撰寫過程中,官方就更新 aws-sdk-react-native 的說明了,是說官方比較推薦去使用 AWS JavaScript SDK with React Native support,不過本文還是維持原本使用的 aws-sdk-react-native
這套進行實作,因為這套實在太多坑啦!就算看了說明檔還是看不懂怎麼使用!😱
以下流程主要是參考 @chunghe 在該 repo Issues 貼出的 detail step-by-step guide 進行步驟:
打包
- 首先要做的是自己打包(pack)一份
aws-sdk-react-native
,請先下載 AWS Mobile iOS SDK 2.4.16 版(官網下載頁目前放上的 iOS 2.5+ 版跟本文流程不相容),然後解壓縮 - 然後把 aws-sdk-react-native 專案下載下來,可以用
git clone https://github.com/awslabs/aws-sdk-react-native.git
- 把步驟 1 中解壓縮的資料夾打開,進入
frameworks
資料夾,找到AWSCore.framework
,將它複製到aws-sdk-react-native
資料夾中的Core/src/ios/Frameworks/
資料夾底下 - 然後
aws-sdk-react-native/Core/src/AWSCognitoCredentials.js
有個 JavaScript bug 😫 打包前要自己手動修正。請將第 48 行的:listener.addListener("LoginsRequestedEvent", async {callbackId} => {
改為
listener.addListener("LoginsRequestedEvent", async ({callbackId}) => {
- 接著進入
aws-sdk-react-native/Core/
,鍵入以下指令進行打包(pack):npm pack
- 好了,打包完就有個名為
aws-sdk-react-native.tgz
的打包檔了,沒有操作錯誤的話,它大概有8.3MB
。接下來把它 copy 到專案目錄下並改個名字吧,我是放在專案目錄/aws-sdk-react-native/
底下,並更名為aws-sdk-react-native-core-0.0.2-with-awscore-framework.tgz
。
安裝到專案中
- 透過
yarn
安裝到專案中:yarn add ./aws-sdk-react-native/aws-sdk-react-native-core-0.0.2-with-awscore-framework.tgz
- 然後 link 它:
react-native link aws-sdk-react-native-core
- 打開專案的 Xcode 檔案(在
ios/
底下可能是xxx.news.xcodeproj
,有用 Pods 的話就是xxx.xcworkspace
),確認Targets
是目前的專案名稱:然後切換到 General 的頁籤,往下捲動直到找到 Embedded Binaries,按下下方的
+
按鈕。 - 在新跳出的視窗中,點擊左下角的
Add Other...
,尋找專案目錄底下node_modules/aws-sdk-native-core/ios/Frameworks/
中的AWSCore.framework
檔案,選定之後按下Open
。 - 在下一個跳出的視窗中,請確認 不要勾選
Destination: Copy items if needed
的選項,因為這個檔案已經在專案目錄的node_modules/aws-sdk-native-core/ios/Frameworks/
目錄底下囉。好了之後請按下Finish
。 - 操作無誤的話會看到下圖這樣:
- 接下來請切換到 Build Phases 頁籤,並點擊左上角的
+
按鈕,選擇New Run Script Phase
。 - 請確認新增的
Run Script
區塊是在Embed Frameworks
區塊之下的,不是的話請拖曳改變順序。然後展開Run Script
,確認Shell
是/bin/sh
,接著在下方文字框輸入:bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCore.framework/strip-frameworks.sh"
接著要確認下面四個部分
Show environment variables in build log
已勾選、Run script only when installing
未勾選、Input Files
與Output Files
都是空的。如圖: - 最後,請切換至
Build Settings
頁籤,找到Search Paths
底下的Framework Search Paths
(如果覺得選項太多不好找,可利用右上角的搜尋框),加入$(SRCROOT)/../node_modules/aws-sdk-react-native-core/ios/Frameworks
。好了,這樣套件就安裝完成了,可以試著 Build 看看,若沒有遇到 Fail 的話應該就是沒問題的。
Amazon Cognito 設定
假設已經申請好 AWS 的帳號了,請連到 Amazon Cognito 開始接下來的步驟:
- 到首頁請選擇「開始使用 Amazon Cognito」,連過去之後又有兩顆按鈕,因為這次的任務是要用第三方社群身分驗證進行登入,所以選擇右邊的 Manage Federated Identities。
- 點擊
Create new identity pool
建立新的身分池。 - 給這個 pool 一個名字吧,例如
My App
。然後展開Authentication providers
,可以看到各式各樣的 providers,本例要設定的是 Facebook 與 Google,但是請 注意!若你有多個平台需要使用同一組 Google 身分,在 Google 的部份請透過 OpenId 進行設定喔!否則就會在不同平台登入的同一組 Google 帳號(例如 Web 跟 iOS 裝置登入的 Google 帳號)會被視為不同的身分! - 由於下面介紹
react-native-facebook-login
及react-native-google-signin
時,會介紹 Facebook 與 Google 應用程式的設定步驟,因此這邊就先跳過,只要知道之後會回來這邊設定 Facebook 與 OpenID 的部份即可。先留著這個視窗,晚點回來繼續完成。