iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Mobile Development

我的 Flutter 進化論:30 天打造「Crew Up!」的架構之旅系列 第 13

Day 13 - Firebase 專案設定:從多環境管理到雲端整合

  • 分享至 

  • xImage
  •  

在 Day 12 完成 UI 測試架構後,我們要開始建立 CrewUp 的雲端基礎設施。今天我們要解決一個實際專案中很重要的問題:如何同時處理多環境管理和 Firebase 整合

從專案開發的經驗來看,這兩個需求往往會一起出現:我們需要不同的開發環境來測試功能,同時也需要雲端服務來儲存資料。今天就來分享我們在 CrewUp 專案中的實際作法。

🎯 為什麼選擇 Firebase?專案實務考量

開發效率的實際體驗

在 CrewUp 專案中,我們選擇 Firebase 的考量主要有這幾個面向:

零設定的開發體驗

  • 不用架設資料庫伺服器,專注在 App 功能開發
  • 認證系統直接可用,包含 Google 登入、Email 註冊等
  • 檔案上傳功能內建,頭像和活動圖片處理變得簡單

即時功能很實用

  • 活動參與狀況可以即時更新給所有成員
  • 聊天功能的基礎建設已經準備好
  • 推播通知整合度很高

成本控制比較容易
在專案初期,Firebase 的 Spark(免費)計畫提供了一些足以支撐 MVP 階段的免費額度,例如:

  • Firestore:每天 50,000 次讀取、20,000 次寫入、20,000 次刪除,1 GB 儲存空間
  • Storage注意 Firebase Storage 政策已更新,新專案需要 Blaze 方案,建議評估成本後再決定是否使用(詳細定價
  • Authentication(非電話驗證方式):帳號總數無明顯上限,但對每日活躍登入、驗證相關操作有頻率限制
  • 所以說「成本控制比較容易」在早期通常是成立的,但建議留意使用量、API 操作頻次與政策變動,以防超出免費額度造成服務中斷或不可預期限制

CrewUp 的技術架構選擇

Firebase 特別適合我們的應用情境:

  • 社群活動 App:需要即時更新參與狀況
  • 多平台支援:iOS 和 Android 使用同一套 SDK
  • 離線使用:Cache 機制讓 App 在網路不穩時也能運作
  • 安全考量:Google 的基礎設施讓我們比較放心

📋 多環境管理:Flutter Flavorizr 的實戰應用

遇到的實際問題

在開發 CrewUp 的過程中,我們發現需要同時維護幾個不同的版本:

  • 開發版本:測試新功能,可能會有很多 bug
  • 測試版本:給 QA 和 beta 使用者測試的相對穩定版本
  • 正式版本:上架到 App Store 和 Google Play 的版本

如果只有一個版本,開發過程中可能會遇到這些情況:

  • 開發時要測試新功能,但會影響到現有的測試資料
  • 想給朋友試用,但怕開發版本太不穩定
  • 要上架但不確定功能是否穩定

Flutter Flavorizr:我們選擇的解決方案

在比較了幾種作法後,我們發現 Flutter Flavorizr 是不錯的選擇:

為什麼我們不選擇手動設定?

  • 需要分別設定 Android 和 iOS 的設定檔,比較容易出錯
  • 每次新增環境都要手動改一堆檔案
  • 團隊成員容易搞混不同環境的設定

Flavorizr 有哪些好處?

  • 一次設定,自動產生所有平台的設定檔
  • 不同環境可以用不同的 App 圖示和名稱,一看就能知道是哪個版本
  • 建構指令比較簡單,不會搞混
  • 每個環境可以有獨立的 Bundle ID,可以同時安裝在同一支手機上

CrewUp 專案的 Flavorizr 設定

在我們專案中,可以參考這樣的 pubspec.yaml Flavorizr 設定:

# pubspec.yaml
flavorizr:
  # 自動建立這些設定檔
  instructions:
    - assets:downloadIcons
    - android:androidManifest
    - android:buildGradle
    - flutter:flavors
    - flutter:app
    - flutter:main
    - ios:podfile
    - ios:xcconfig
    - ios:buildTargets
    - ios:schema
    - ios:plist

  # 三個環境的設定
  flavors:
    # 開發環境:橘色圖示,方便辨識
    development:
      app:
        name: "Crew Up Dev"
      android:
        applicationId: "com.example.crewup.develop"
      ios:
        bundleId: "com.example.crewup.develop"
        displayName: "Crew Up Dev"

    # 測試環境:黃色圖示,給測試人員使用
    staging:
      app:
        name: "Crew Up Staging"
      android:
        applicationId: "com.example.crewup.staging"
      ios:
        bundleId: "com.example.crewup.staging"
        displayName: "Crew Up Staging"

    # 正式環境:藍色圖示,上架版本
    production:
      app:
        name: "Crew Up"
      android:
        applicationId: "com.example.crewup"
      ios:
        bundleId: "com.example.crewup"
        displayName: "Crew Up"

實際執行和使用

安裝和設定

# 1. 在 pubspec.yaml 中加入依賴
dev_dependencies:
  flutter_flavorizr: ^2.4.1

# 2. 執行指令產生設定檔
flutter packages pub run flutter_flavorizr

# 3. 清理和重新建構
flutter clean && flutter pub get

執行後,Flavorizr 會自動產生:

  • lib/flavors.dart:環境管理的程式碼
  • lib/main_development.dartlib/main_staging.dartlib/main_production.dart:不同環境的入口檔案(已實作)
  • Android 和 iOS 的各環境設定檔

建構不同環境的 App

使用 --flavor 參數來指定環境:

# 建構開發版本
flutter build apk --flavor development -t lib/main_development.dart

# 建構測試版本  
flutter build apk --flavor staging -t lib/main_staging.dart

# 建構正式版本
flutter build apk --flavor production -t lib/main_production.dart

# 直接執行特定環境(開發時很方便)
flutter run --flavor development -t lib/main_development.dart

實際使用的好處

  • 三個版本可以同時安裝在手機上,不會互相覆蓋
  • 一看 App 名稱就知道是哪個環境
  • 開發時不用擔心影響到測試或正式環境的資料

🔧 常見問題與解決方案

在實際使用 Flavorizr 和 Firebase 的過程中,開發過程中可能會遇到一些問題,這裡分享一些我們用過的解決方法:

Flavorizr 執行失敗

# 問題:執行 flutter packages pub run flutter_flavorizr 時出現錯誤
# 解決方案:
# 1. 確保 Flutter 版本相容
flutter --version

# 2. 清理專案並重新安裝依賴
flutter clean && flutter pub get

# 3. 檢查 pubspec.yaml 格式是否正確
# 確保縮排使用空格,不要混用 Tab

Firebase 設定檔遺失或損壞

# 問題:google-services.json 或 GoogleService-Info.plist 遺失
# 解決方案:重新下載設定檔
flutterfire configure --project=your-project-id

# 或者手動從 Firebase Console 下載
# Android: Project Settings > Your apps > Download google-services.json
# iOS: Project Settings > Your apps > Download GoogleService-Info.plist

多環境切換注意事項

  • Bundle ID 衝突:確保每個環境的 Bundle ID 都不同
  • Firebase 專案權限:檢查不同環境的 Firebase 專案權限設定
  • 推播通知設定:測試環境可能需要不同的 FCM 設定
  • 環境變數:確保建構時正確傳入環境參數

建構錯誤處理

# 問題:建構時找不到 flavor
# 解決方案:檢查建構指令是否正確
flutter build apk --flavor development -t lib/main_development.dart

# 問題:iOS 建構失敗
# 解決方案:清理 iOS 快取
cd ios && pod deintegrate && pod install

Firebase 初始化錯誤

// 問題:Firebase 初始化失敗
// 解決方案:檢查 firebase_options.dart 是否正確產生
// 確保 DefaultFirebaseOptions.currentPlatform 能正確識別平台

🔥 Firebase 專案設定

CrewUp 使用的 Firebase 服務

在我們專案中,目前有使用到這些 Firebase 服務:

目前已整合的服務:

  • Firebase Authentication:Google 登入、Email 註冊
  • Cloud Firestore:儲存活動資料、使用者資料、訊息
  • Firebase Storage:上傳頭像、活動圖片
  • Firebase Cloud Messaging:推播通知

開發中的服務:

  • Firebase Crashlytics:App 穩定性監控,自動收集錯誤報告
  • Firebase Analytics:使用者行為分析,了解功能使用情況

Firebase 多專案架構:最佳實踐策略

從我們的開發經驗來看,建議為不同環境建立獨立的 Firebase 專案。這樣不僅能從源頭避免資料污染和安全風險,也比較符合團隊合作的工作流程。

Firebase 專案建立步驟

1. 建立三個獨立的 Firebase 專案

前往 [Firebase Console] 建立三個專案:

為什麼要分開?

  • 資料隔離:開發環境可以隨意測試,不怕資料被誤刪或污染
  • 安全考量:測試環境有穩定的測試資料,不會被開發過程影響
  • 生產保護:正式環境完全獨立,確保使用者資料安全
  • 成本控制:雖然會增加專案數量,但能避免誤操作造成的損失

開發環境專案:

  • 專案名稱:example-crewup-dev
  • 啟用 Google Analytics:否(開發階段不需要)
  • 選擇地區:asia-east1(台灣彰化資料中心)

測試環境專案:

  • 專案名稱:example-crewup-staging
  • 啟用 Google Analytics:是(測試使用者行為)
  • 選擇地區:asia-east1(台灣彰化資料中心)

正式環境專案:

  • 專案名稱:example-crewup-prod
  • 啟用 Google Analytics:是(分析正式使用者行為)
  • 選擇地區:asia-east1(台灣彰化資料中心)

2. 使用 FlutterFire CLI 設定多專案

為每個環境設定對應的 Firebase 專案:

開發環境設定:

# 設定開發環境專案
flutterfire configure --project=example-crewup-dev --platforms=android,ios

測試環境設定:

# 設定測試環境專案
flutterfire configure --project=example-crewup-staging --platforms=android,ios

正式環境設定:

# 設定正式環境專案
flutterfire configure --project=example-crewup-prod --platforms=android,ios

通用設定指令:

# 安裝工具
npm install -g firebase-tools
dart pub global activate flutterfire_cli

# 登入 Firebase
firebase login

# 自動設定專案(選擇對應的專案)
flutterfire configure

這個指令會為每個環境產生對應的設定檔:

開發環境:

  • 自動產生 lib/firebase_options_dev.dart
  • 下載 Android 的 google-services-dev.json
  • 下載 iOS 的 GoogleService-Info-dev.plist

測試環境:

  • 自動產生 lib/firebase_options_staging.dart
  • 下載 Android 的 google-services-staging.json
  • 下載 iOS 的 GoogleService-Info-staging.plist

正式環境:

  • 自動產生 lib/firebase_options_prod.dart
  • 下載 Android 的 google-services-prod.json
  • 下載 iOS 的 GoogleService-Info-prod.plist

通用設定檔:

  • 自動產生 lib/firebase_options.dart
  • 下載 Android 的 google-services.json
  • 下載 iOS 的 GoogleService-Info.plist

與 Flavorizr 結合:多專案自動切換

現在我們有了三個獨立的 Firebase 專案,接下來要讓 Flavorizr 能夠根據不同環境自動載入對應的 Firebase 設定。

多專案配置的實際應用

在我們專案中,lib/flavors.dart 檔案是 Flavorizr 自動產生的:

// lib/flavors.dart

// (imports omitted)

enum Flavor {
  development,
  staging,
  production,
}

class F {
  static Flavor? appFlavor;

  static String get name => appFlavor?.name ?? '';

  static String get title {
    switch (appFlavor) {
      case Flavor.development:
        return 'Crew Up Dev';
      case Flavor.staging:
        return 'Crew Up Staging';
      case Flavor.production:
        return 'Crew Up';
      default:
        return 'title';
    }
  }
}

環境相關的設定

我們可以根據不同環境做不同的設定:

// lib/main_production.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 從 --flavor 參數取得環境設定
  const flavor = String.fromEnvironment('FLAVOR', defaultValue: 'production');
  F.appFlavor = Flavor.values.firstWhere(
    (element) => element.name == flavor,
    orElse: () => Flavor.production,
  );

  // Initialize Firebase
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  // Initialize Firebase Cloud Messaging
  await FCMService.initialize();

  // 其他初始化...
  runApp(UncontrolledProviderScope(container: container, child: const App()));
}

🚀 專案中的實際成果

經過這次的設定,我們的 CrewUp 專案目前具備了這些功能:

✅ 已經在運作的功能

  • Firebase Authentication:Google 登入和 Email 註冊都可以正常使用
  • Cloud Firestore:活動資料、使用者資料都儲存在雲端
  • Firebase Storage:頭像和活動圖片上傳功能正常
  • Firebase Cloud Messaging:推播通知可以送到使用者手機
  • Flutter Flavorizr:三個環境可以獨立建構和測試(使用 --flavor 參數自動切換)

🔧 開發中的功能

  • Firebase Crashlytics:自動收集 App 當機報告,幫助我們快速修復問題
  • Firebase Analytics:了解使用者最常用哪些功能,優化使用體驗

💡 實際開發中的好處

多環境管理很方便

  • 開發時可以隨意測試,不會影響正式資料
  • 給測試人員的版本穩定,不會有開發中的功能
  • 三個版本可以同時裝在同一支手機上比較

Firebase 整合度很高

  • 使用者登入後,所有服務都可以直接使用
  • 離線時資料會自動快取,網路恢復時同步
  • 安全規則可以保護使用者資料不被誤用

🔧 目前的開發規劃

目前的實作狀況:

  1. 多環境 Firebase 專案:在我們專案中建立了三個獨立的 Firebase 專案
    • 實作成果:三個環境完全獨立,資料隔離和安全性已達成
    • 開發環境:獨立專案,可以隨意測試新功能
    • 測試環境:獨立專案,提供穩定的測試資料
    • 正式環境:獨立專案,保護正式用戶資料
    • 成本效益:雖然增加了專案數量,但避免了誤操作風險
  2. 資料存取最佳化:持續改善 Firestore 查詢效率和離線支援

正在開發的功能:

  1. Crashlytics 錯誤監控:自動追蹤 App 穩定性,讓我們能快速發現和修復問題
  2. Analytics 使用者行為分析:了解使用者如何使用 App,優化功能設計
  3. Performance Monitoring:監控 App 在不同裝置上的表現

下一步

明天,我們將深入探討 Firebase Authentication 的實際應用,學習如何處理使用者登入狀態管理,以及如何整合 Google 登入功能到我們的專案中。

希望這些經驗對大家有幫助,我們明天 Day 14 再繼續!


📋 相關資源

📝 專案資訊

  • 專案名稱: Crew Up!
  • 開發日誌: Day 13 - Firebase 專案設定:從多環境管理到雲端整合
  • 文章日期: 2025-09-27
  • 技術棧: Flutter, Firebase, Flavorizr, Riverpod

上一篇
Day 12 - UI 測試實戰:打造穩固的架構防護網
下一篇
Day 14 - Firebase Authentication:從 Google 登入到完整認證系統
系列文
我的 Flutter 進化論:30 天打造「Crew Up!」的架構之旅16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言