Flutter 如何根據 Flavor 多環境載入對應的 Firebase Config
本文的內容應該很多人都會碰到,我們很常為了加速開發,會使用許多 Firebase 服務,例如:Authentication、Analytics 和 Crashlytics 等等,這時候就需要處理 Flutter 專案與 Firebase 的集成,而當我們有多個環境時如何綁定對應的 Firebase 專案?如何決定要載入哪個環境的設定檔,才能與 Firebase 服務溝通。其中比較麻煩是針對 Android、iOS(macOS相同) 有不同處理方式,但也大同小異,趕緊往下滑跟著實作吧!
Firebase Console
本文範例設置了兩個環境,分別為 Dev、Prod,所以 Firebase Project 也區分開來,之後在設定及維護上會方便許多。當然如果你還有 staging 或是其他環境那就在創建自己的專案,我們需要從每個專案裡拿到設定檔
FlutterFire Helper
為了不需要手動為每個平台一個一個新增到專案,我們需要 FlutterFire 工具的幫忙,它的出現就是為了讓開發者可以快速將 Flutter 專案集成 Firebase,替我們節省非常多時間
設定過程我們都需要 flutterfire_cli
指令操作,在 Terminal 透過幾個指令就能完成了,需要先進行安裝
dart pub global activate flutterfire_cli
接著在 Terminal 移動到 Flutter 專案的所在位置,使用 flutterfire configure
指令,最後產出幾個設定firebase_options 檔案
project
為 Firebase 專案名稱out
為輸出的位置與檔案名稱ios-bundle-id
為 Bundle IDandroid-app-id
為 Package Namemacos-bundle-id
為 Bundle IDweb-app-id
為 Bundle ID
每個平台的 id 通常應該沒特別需求的話都會是相同,運行之後會詢問你要使用服務的平台,包含 ios、android、macos、web,最後產出幾個設定檔案
flutterfire config \
--project=flaver-dev \
--out=lib/firebase_options_dev.dart \
--ios-bundle-id=com.flaver.food.dev \
--android-app-id=com.flaver.food.dev \
--macos-bundle-id=com.flaver.food.dev \
--web-app-id=com.flaver.food.dev
- Android 需要
google-services.json
- iOS 與 macOS 需要
GoogleService-Info.plist
、firebase_app_id_file.json
- Flutter 需要
firebase_options.dart
而在每次執行 flutterfire configure
指令後就先將檔案進行移動,避免之後在生成其他環境的檔案時造成覆蓋,要移動到哪呢?可以跳到後面的 Setup 操作。
以下為 Firebase 專案完成平台設定的情況,一下子就完成了,接下來只需要讓程式知道在每個環境下要載入對應的檔案和資料
Android Setup
當我們設置好 Flavor 之後 android
目錄會有各環境的資料夾,我們需要將 google-services.json
放置到對應環境底下,此範例為 dev 和 prod
Android 會在 app
資料夾載入 google-services.json
檔案,所以我們需要在 Build 階段將運行環境的檔案複製到 app
這層,這樣才會正常運行哦
iOS Setup
當我們設置好 Flavor 之後 iOS
目錄會有 GoogleService-Info.plist
、firebase_app_id_file.json
兩個檔案,一個會在 Runner
資料夾裡面,需要將他們放置到 flavor 資料夾,此範例為 dev 和 prod。不過這都沒有固定,你想放到哪裡都可以,最主要是好管理就好
此範例有創建 Config
資料夾,會了放置相關檔案,而因為要讓專案讀取的到,所以在 Build Phases 的 Copy Bundle Resources
需要加入資料夾
因為要讓 iOS 在 Build 階段將檔案移動到指定地點,跟 Android 一樣,需要多新增兩個任務處理。在 Build Phases
裡新增一個任務 Copy GoogleServices file(可以自行命名),在 Build 過程需要給予對應環境的 GoogleService-Info.plist
,讓 APP 在每個環境運行時能載入正確的 Firebase 設定檔,才可以正常使用 Firebase 服務
environment="dev"
# Get flavor name
if [[ $CONFIGURATION =~ -([^-]*)$ ]]; then
environment=${BASH_REMATCH[1]}
fi
GOOGLESERVICE_INFO_PLIST_NAME=GoogleService-Info.plist
GOOGLESERVICE_INFO_PLIST_FILE_PATH=${PROJECT_DIR}/Config/${environment}/${GOOGLESERVICE_INFO_PLIST_NAME}
# Check GoogleService-Info.plist file are exist or not
if [ ! -f $GOOGLESERVICE_INFO_PLIST_FILE_PATH ]
then
echo "No GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1
fi
PLIST_FILE_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist
# Copy GoogleService-Info.plist of prod for Release build
cp "${GOOGLESERVICE_INFO_PLIST_FILE_PATH}" "${PLIST_FILE_DESTINATION}"
echo "Copy ${GOOGLESERVICE_INFO_PLIST_FILE_PATH} to final destination: ${PLIST_FILE_DESTINATION}"
如果有使用到 Firebase Crashlytic 服務,Build Phases
會有 [firebase_crashlytics] Crashlytics Upload Symbols 這個任務,這時候需要針對擁有的 flavor 環境載入對應的檔案,可能會需要微調一下,將 Configuration 和路徑調整為自己專案的樣子
if [ "${CONFIGURATION}" == "Debug-dev" ] || [ "${CONFIGURATION}" == "Profile-dev" ] || [ "${CONFIGURATION}" == "Release-dev" ];
then
"$PODS_ROOT/FirebaseCrashlytics/upload-symbols" --flutter-project "$PROJECT_DIR/Config/dev/firebase_app_id_file.json"
elif [ "${CONFIGURATION}" == "Debug-prod" ] || [ "${CONFIGURATION}" == "Profile-prod" ] || [ "${CONFIGURATION}" == "Release-prod" ];
then
"$PODS_ROOT/FirebaseCrashlytics/upload-symbols" --flutter-project "$PROJECT_DIR/Config/prod/firebase_app_id_file.json"
fi
如果沒有使用到 Firebase Crashlytic,就不會使用到
firebase_app_id_file.json
,也不需要額外設定
Flutter Setup
在 flutterfire 生成檔案後,會在 lib
資料夾生成 firebase_options.dart
,我們一樣將他們放置到其他資料夾存放,為了專案目錄架構的整潔,然後在檔名後方加上環境後綴
最後一步,在每個環境的入口,main()
使用對應的 Firebase 設定檔,讓我們在 Firebase 初始化時沒有問題,接下來就能安心開發了,很棒對吧
Firebase Service Verification
本文使用 Firebase Crashlytics 作為範例,測試是否可以正常與 Firebase 服務互動。在 main() 使用
runZonedGuarded()
包裹,為了要捕捉未知的 Platform Error,我們在 runApp()
之前就拋出測試用的例外,為了讓下方的 callback 可以被觸發,這時候就會將相關的錯誤以及 StackTrace 上傳給 Firebase Crashlytics 囉
當有看到 Making request to crashlyticsreports domain 的時候就代表運作正常,此時在 Crashlytics 後台可以看到原本的添加SDK文字消失,並顯示分析儀表板
到這邊看到有資料進來就代表服務運作沒問題了,也記得檢查和測試每個環境是否都正常,如果你在設定 Firebase 過程中還是有遇到問題,也很歡迎留言跟我討論~
- 學會運用 Flutter Widgetbook,該管好自己和公司的元件庫了!
- 剛進入 Flutter 嗎?適合初學者食用,GetX 是否適合你呢!
- 教你為 Riverpod 2.0 撰寫 Flutter 測試 part.1
- 教你為 Riverpod 2.0 撰寫 Flutter 測試 part.2
- 輕鬆了解 Isar NoSQL DB,用它來實作 Flutter 資料庫吧!
- Flutter 輕鬆實作 i18n,使用 easy_localization_generator 就對了
- Flutter CICD 使用 Gitlab Runner 和 App Center 實作 part.1
- Flutter CICD 使用 Gitlab Runner 和 App Center 實作 part.2
- 使用 CodeMagic 和 Firebase 實現 Flutter CICD
- 輕鬆完成Flutter開發環境,最新版!
- 實作Flutter多變有趣的滾動效果CustomScrollView!
- 如何在Flutter使用 Makefile 節省你的時間?
- Easily understand StatefulWidget LifeCycle of Flutter
- “freezed” makes model class strong and easily
- 提高Flutter性能的小技巧!(一)
- 提高Flutter性能的小技巧!(二)
- 提高Flutter性能的小技巧!(三)
- What are Async and Isolates in Flutter?
- LoadBalancer is optimization for Isolates in Flutter
- Riverpod 輕鬆學,原來這麼好用!
- Riverpod 輕鬆學(二),一些進階用法!
About
- GitHub:
- Instagram:
- Linkedin:
- Youtube:
- Youtube: (美食頻道)
- Email: [email protected]
Contribution
如果覺得文章不錯的話可以贊助,讓我有更多動力和熱情分享學習紀錄和生活!
希望有幫助到你/妳,歡迎追蹤我,方便瀏覽最新的文章~