Skip to content

解决 Flutter 中 'Failed to load FirebaseOptions from resource' 错误

问题描述

在 Flutter 项目中初始化 Firebase 时调用 await Firebase.initializeApp() 后出现以下错误:

E/flutter ( 6571): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(java.lang.Exception: Failed to load FirebaseOptions from resource. Check that you have defined values.xml correctly., Exception, Cause: null, Stacktrace: java.lang.Exception: Failed to load FirebaseOptions from resource.

此错误通常发生在以下环境:

  • 使用 Flutter 3.19+ 版本
  • 迁移到声明式 Gradle 插件应用(移除了旧的 apply from 命令)
  • 仅添加 google-services.json 文件而缺少完整配置
  • iOS 和 Android 平台项目(非 Web)

核心问题

Flutter 3.19+ 改变了 Firebase 配置的加载方式,不再自动从资源文件中读取配置,需要显式提供 FirebaseOptions 参数。

解决方案

方案一:使用 FlutterFire CLI 自动生成配置(推荐)

这是官方推荐的最新配置方法,支持多平台和环境:

步骤

  1. 安装 FlutterFire CLI

    bash
    dart pub global activate flutterfire_cli
  2. 生成配置文件

    bash
    flutterfire configure

    该命令会:

    • 自动创建 lib/firebase_options.dart 文件
    • 配置所有支持的平台(iOS/Android)
    • 同步 Firebase 项目设置
  3. 在代码中引入配置

    dart
    import 'package:your_app/firebase_options.dart';
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      runApp(MyApp());
    }

文件结构示例

lib/
└── firebase_options.dart ⬅️ 自动生成
android/
└── app/
    └── google-services.json
ios/
└── Runner/
    └── GoogleService-Info.plist

重要

如果项目已存在旧版配置,请确保删除以下冲突插件:

yaml
# 从 pubspec.yaml 移除
firebase_core_web
firebase_analytics_web
firebase_auth_web
# ...其他 web 插件

方案二:手动配置 FirebaseOptions

需要显式提供 Firebase 凭据参数:

dart
await Firebase.initializeApp(
  options: FirebaseOptions(
    apiKey: 'AIzaSyA...',     // google-services.json 中的 "api_key"
    appId: '1:123...',        // google-services.json 中的 "mobilesdk_app_id"
    messagingSenderId: '123', // google-services.json 中的 "project_number"
    projectId: 'my-project',  // google-services.json 中的 "project_id"
    storageBucket: 'my-app.appspot.com', // 可选
  ),
);

多环境配置示例(开发/生产)

dart
if (Platform.isAndroid) {
  final options = environment == AppEnvironment.development 
    ? const FirebaseOptions( // 开发环境
        apiKey: "DEV_KEY",
        appId: "DEV_ID",
        messagingSenderId: "DEV_SENDER_ID",
        projectId: "DEV_PROJECT_ID",
      )
    : const FirebaseOptions( // 生产环境
        apiKey: "PROD_KEY",
        appId: "PROD_ID",
        messagingSenderId: "PROD_SENDER_ID",
        projectId: "PROD_PROJECT_ID",
      );
  
  await Firebase.initializeApp(options: options);
}

参数位置

参数值必须从对应环境的 google-services.json (Android)或 GoogleService-Info.plist (iOS) 中获取:

  • apiKeyapi_key
  • appIdmobilesdk_app_id
  • messagingSenderIdproject_number
  • projectIdproject_id

方案三:检查 Gradle 与包名(Flavors 场景)

如果是多产品变体(Flavors)项目,需检查以下配置:

  1. build.gradle 文件
    确保包名与 Firebase 控制台注册的一致

    gradle
    android {
      namespace "com.yourcompany.app" // 必须匹配 Firebase 包名
      // ...
    }
  2. AndroidManifest.xml 文件

    xml
    <manifest 
      package="com.yourcompany.app"  <!-- 与 namespace 一致 -->
  3. MainActivity.kt 文件

    kotlin
    package com.yourcompany.app // 必须匹配

常见错误

修改包名后必须同时更新:

  1. Firebase 控制台的应用注册信息
  2. Gradle 中的 namespace
  3. AndroidManifest.xml 中的 package
  4. Kotlin 类文件头部的 package

核心问题说明

为何新版本要求显式 Options 参数?

Flutter 3.19+ 引入的声明式 Gradle 插件需要:

  1. 平台统一性 - iOS/Android 配置标准化
  2. 环境隔离 - 支持开发/生产多环境
  3. 安全性 - 避免敏感信息误打包

经典错误场景对照表

错误场景解决方案
仅添加 google-services.json使用 FlutterFire CLI 或手动 Options
迁移后 Gradle 配置缺失检查项目级 build.gradle 插件
iOS 15.4 特有错误使用 currentPlatform 自动过滤
产品变体(Flavor)环境错误检查包名三处一致性

总结要点

  1. 不再支持仅添加 JSON/PLIST 文件的自动配置
  2. 必须在使用 Firebase.initializeApp() 时提供 options
  3. 最佳实践是使用 flutterfire configure 生成配置
  4. 多环境项目需在代码中动态切换 Options
  5. 包名更改后需同步 Firebase 控制台和所有配置项

完成上述任一配置方案后,重新运行应用即可解决:

bash
flutter clean && flutter run