You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Flutter项目配置两个Firebase项目,实现生产与预发布环境分离

单个Flutter项目配置双Firebase环境(生产/测试)解决方案

针对iOS平台GoogleService-Info.plist无法重名的问题,目前最成熟的方案是通过构建脚本/编译变种自动切换配置文件,结合Flutter层环境标识实现数据隔离。以下是分步实现指南:

1. 配置文件目录规划

先把两个环境的Firebase配置文件分开存放,避免冲突:

  • 在项目根目录创建firebase_configs文件夹
  • 内部新建dev(预发布/测试)和prod(生产)子文件夹
  • 将对应环境的GoogleService-Info.plist(iOS)、google-services.json(Android)分别放入两个子文件夹

2. iOS平台:构建前自动切换配置文件

利用Xcode的Run Script Phase,在编译前自动复制对应环境的plist文件到指定位置:

  1. 打开ios/Runner.xcworkspace,选中Runner Target
  2. 切换到Build Phases标签,点击+选择New Run Script Phase
  3. 将以下脚本粘贴到脚本框中(可根据自己的编译配置调整判断逻辑):
# 根据编译配置切换环境
if [ "${CONFIGURATION}" = "Debug" ] || [ "${CONFIGURATION}" = "AdHoc" ]; then
  # 测试环境:复制dev目录下的plist到Runner目录
  cp "${PROJECT_DIR}/../firebase_configs/dev/GoogleService-Info.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
else
  # 生产环境:复制prod目录下的plist到Runner目录
  cp "${PROJECT_DIR}/../firebase_configs/prod/GoogleService-Info.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
fi
  1. 确保Runner项目中已添加GoogleService-Info.plist,并勾选Target Membership中的Runner

3. Android平台:用编译变种(Product Flavors)隔离环境

Android原生支持通过Product Flavors加载不同环境的配置文件:

  1. 打开android/app/build.gradle
  2. 在android代码块中添加编译变种配置:
android {
    // ...其他原有配置
    flavorDimensions "environment"
    productFlavors {
        dev {
            dimension "environment"
            applicationIdSuffix ".dev" // 给测试包加后缀,避免与生产包冲突
            resValue "string", "app_name", "MyApp Dev" // 可选:修改测试包名称
        }
        prod {
            dimension "environment"
            resValue "string", "app_name", "MyApp"
        }
    }
}
  1. 将dev环境的google-services.json放入android/app/src/dev/,prod环境的放入android/app/src/prod/
  2. Google Services插件会自动根据当前编译变种加载对应配置文件

4. Flutter代码层识别环境并适配逻辑

通过编译参数或平台标识判断当前环境,实现业务逻辑的环境隔离:

方式一:通过--dart-define传递环境变量

构建时携带环境参数:

# 测试环境
flutter run --dart-define=ENV=dev
# 生产环境
flutter run --dart-define=ENV=prod

在Flutter代码中读取并使用:

enum Env { dev, prod }

final currentEnv = String.fromEnvironment('ENV', defaultValue: 'prod') == 'dev' 
    ? Env.dev 
    : Env.prod;

// 示例:根据环境初始化不同配置
void initFirebase() async {
  await Firebase.initializeApp();
  // 可根据currentEnv添加环境专属逻辑,比如测试环境启用调试日志
  if (currentEnv == Env.dev) {
    FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080); // 可选:连接本地模拟器
  }
}

方式二:根据平台编译标识判断(无需额外参数)

针对Android的Product Flavors和iOS的Configuration,通过平台通道读取当前环境:

import 'package:flutter/services.dart';

Future<Env> getCurrentEnv() async {
  try {
    final String env = await MethodChannel('com.example/env').invokeMethod('getEnv');
    return env == 'dev' ? Env.dev : Env.prod;
  } catch (_) {
    return Env.prod;
  }
}

(需在iOS/Android原生代码中实现getEnv方法返回当前环境标识)

注意事项

  • 将ios/Runner/GoogleService-Info.plist和android/app/google-services.json添加到.gitignore,避免提交自动生成的文件,仅提交firebase_configs下的配置文件
  • iOS测试包和生产包的Bundle ID需保持一致或通过Application ID后缀区分,避免App Store审核冲突
  • Android通过Product Flavors生成的测试包与生产包可共存于同一设备,无需卸载

内容的提问来源于stack exchange,提问作者Jaden Watt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:40:37