Android product flavors (.dev/.staging suffixes, prod clean) + per-flavor
Dart entrypoints, dart-define env files, and per-flavor Firebase config for
both platforms across 3 projects (halobestie-clone-dev / my-bestie-876ec /
my-bestie-production).
- Android: flavorDimensions("env") + productFlavors; @string/app_name label;
per-flavor src/<flavor>/google-services.json (clients verified to match each
applicationId).
- iOS: customer app re-based to the EXISTING App Store identity
com.asc.hallobestie (dev/staging suffix it; ships as an update to the live
app). mitra is a new app (com.mybestie.mitra). Per-flavor plists staged in
ios/config/<flavor>/; Xcode scheme wiring deferred (Mac follow-up).
- firebase_options_{dev,staging,prod}.dart filled with real android + iOS
values (regenerated from the native config files).
- BUILD_FLAVORS.md per app documents flavor table, build commands, iOS
identity decision, and the remaining iOS Xcode steps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.4 KiB
Build Flavors — mitra_app (Android)
The mitra_app has three Android build flavors: dev, staging, prod.
Each has its own applicationId, backend URL, app display name, Dart entrypoint,
Firebase Dart options, and google-services.json source set — so all three can
be installed side-by-side on one device.
Scope note: this is Android + Dart + env-files only. iOS Xcode schemes are a separate follow-up and are NOT set up yet.
Flavor matrix
| Flavor | applicationId | API_BASE_URL | App name | Entrypoint | env file |
|---|---|---|---|---|---|
| dev | com.mybestie.mitra.dev |
http://192.168.88.247:3000 |
Mitra HaloBestie Dev | lib/main_dev.dart |
env/dev.json |
| staging | com.mybestie.mitra.staging |
https://staging-api.halobestie.com ⚠️ |
Mitra HaloBestie Staging | lib/main_staging.dart |
env/staging.json |
| prod | com.mybestie.mitra |
https://api.halobestie.com |
Mitra HaloBestie | lib/main_prod.dart |
env/prod.json |
⚠️ The staging API_BASE_URL is a placeholder — confirm the real staging
host and update env/staging.json + lib/firebase/firebase_options_staging.dart.
The applicationId suffix is applied in android/app/build.gradle.kts
(applicationIdSuffix = ".dev" / ".staging"; prod has none). The app name is
emitted per flavor via resValue("string", "app_name", "...") and read by
android/app/src/main/AndroidManifest.xml through android:label="@string/app_name".
Build / run commands
Every command MUST pass --flavor, a matching -t entrypoint, and
--dart-define-from-file for the env. Examples:
Run (debug, on a device/emulator)
flutter run --flavor dev -t lib/main_dev.dart --dart-define-from-file=env/dev.json
flutter run --flavor staging -t lib/main_staging.dart --dart-define-from-file=env/staging.json
flutter run --flavor prod -t lib/main_prod.dart --dart-define-from-file=env/prod.json
Build APK
flutter build apk --flavor dev -t lib/main_dev.dart --dart-define-from-file=env/dev.json
flutter build apk --flavor staging -t lib/main_staging.dart --dart-define-from-file=env/staging.json
flutter build apk --flavor prod -t lib/main_prod.dart --dart-define-from-file=env/prod.json
Build App Bundle (Play Store)
flutter build appbundle --flavor prod -t lib/main_prod.dart --dart-define-from-file=env/prod.json
A bare flutter run (no -t) still works — lib/main.dart delegates to the
dev bootstrap — but it builds with no flavor selected on Android, so prefer the
explicit commands above.
⚠️ CRITICAL warnings
-
--flavoris now mandatory for builds. Once product flavors exist, a bareflutter build apk(without--flavor) FAILS with a Gradle error (no default flavor). Every build/run command must specify--flavorand the matching-t lib/main_<flavor>.dartentrypoint. -
The dev applicationId changed to
com.mybestie.mitra.dev. Any tooling that references the old package id must be updated when running the dev flavor:adbcommands:adb shell pm clear com.mybestie.mitra.dev,adb shell am start ... com.mybestie.mitra.dev/..., etc.- Maestro flows:
appId: com.mybestie.mitra.dev. - Any deeplink / FCM tooling keyed on the package name.
Prod keeps
com.mybestie.mitra; staging iscom.mybestie.mitra.staging.
Firebase config — STATUS: configured ✅ (2026-06-04)
Firebase init is Dart-side (Firebase.initializeApp(options:) in
lib/bootstrap.dart), driven by the per-flavor
lib/firebase/firebase_options_<flavor>.dart. The mitra app is a brand-new
app on both platforms (no legacy App Store identity), so the iOS bundle base
is com.mybestie.mitra — unlike the customer app, which inherits
com.asc.hallobestie.
All apps registered + config in place across 3 projects (one per env):
| Env | Firebase project | Android applicationId | iOS bundle ID |
|---|---|---|---|
| dev | halobestie-clone-dev |
com.mybestie.mitra.dev |
com.mybestie.mitra.dev |
| staging | my-bestie-876ec |
com.mybestie.mitra.staging |
com.mybestie.mitra.staging |
| prod | my-bestie-production |
com.mybestie.mitra |
com.mybestie.mitra |
In place and verified:
android/app/src/<flavor>/google-services.json— all 3, client matches the flavor applicationId.ios/config/<flavor>/GoogleService-Info.plist— all 3, bundle IDs verified.lib/firebase/firebase_options_{dev,staging,prod}.dart— real android + iOS values, no placeholders.
Regenerating after any ID / key change
flutterfire configure --project=halobestie-clone-dev --out=lib/firebase/firebase_options_dev.dart
flutterfire configure --project=my-bestie-876ec --out=lib/firebase/firebase_options_staging.dart
flutterfire configure --project=my-bestie-production --out=lib/firebase/firebase_options_prod.dart
Still TODO — iOS only (Mac/Xcode)
- iOS Xcode schemes + build-phase copy script to select the right
GoogleService-Info.plistper flavor (until then iOS bundles onlyios/Runner/GoogleService-Info.plist). Seeios/config/README.md.
The Google Services Gradle plugin is not applied in this app — Android Firebase init is Dart-side. The
src/<flavor>/google-services.jsonfiles are laid out for if/when that plugin is added.
File map
| File | Purpose |
|---|---|
android/app/build.gradle.kts |
flavorDimensions "env" + productFlavors (id suffix + app_name) |
android/app/src/main/AndroidManifest.xml |
android:label="@string/app_name" |
android/app/src/dev/google-services.json |
dev Firebase config |
android/app/src/{staging,prod}/google-services.json.README |
placeholders — drop real json here |
lib/bootstrap.dart |
shared bootstrap() + App widget |
lib/main.dart |
bare entrypoint → delegates to dev |
lib/main_{dev,staging,prod}.dart |
per-flavor entrypoints |
lib/firebase/firebase_options_{dev,staging,prod}.dart |
per-flavor Dart Firebase options |
env/{dev,staging,prod}.json |
dart-define values (API_BASE_URL, FLAVOR) |