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

Flutter中Firebase初始化异常排查:已在main初始化仍报Firestore错

问题:Flutter中Firebase初始化完成后仍触发Firestore初始化异常

我已在main函数中执行Firebase初始化操作,但在初始化Firestore集合的第一行代码处抛出异常。

UserInfoService代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:xuriti/models/core/user_details.dart';

class UserInfoService{
  CollectionReference userInfoCollection = FirebaseFirestore.instance.collection('userInfo');
UserDetails userDetails =UserDetails();

  addData(UserDetails? userInfo) async {
    await userInfoCollection.doc(userInfo!.user!.sId).set(userInfo.toJson());
    return true;
  }


  Future<UserDetails> getInfo(String? userId)async{
    DocumentSnapshot ds = await userInfoCollection.doc(userId).get();
    if(ds.data() != null){
      return UserDetails.fromJson(ds.data() as Map<String, dynamic>);
    }
    return UserDetails();
  }

}

main.dart中的Firebase初始化代码

import 'dart:io';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

import 'package:flutter_screenutil/flutter_screenutil.dart';

import 'package:provider/provider.dart';
import 'package:xuriti/ui/push_notification/notification.dart';
import 'package:xuriti/ui/routes/router.dart';
import 'firebase_options.dart';
import 'logic/view_models/auth_manager.dart';
import 'logic/view_models/company_details_manager.dart';
import 'logic/view_models/password_manager.dart';
import 'logic/view_models/profile_manager.dart';
import 'logic/view_models/reward_manager.dart';
import 'logic/view_models/trans_history_manager.dart';
import 'logic/view_models/transaction_manager.dart';
import 'models/helper/service_locator.dart';
import 'ui/routes/routnames.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:new_version/new_version.dart';

final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();

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

  runApp(const MyApp());
 

  Firebase.initializeApp().then((value) {
    FirebaseInitialization.sharedInstance.registerNotification();
    FirebaseInitialization.sharedInstance.configLocalNotification();
  });

  

  Firebase.initializeApp().then((value) async {
    FirebaseInitialization.sharedInstance.registerNotification();
    // FirebaseInitialization.sharedInstance.navigate();
    FirebaseInitialization.sharedInstance.configLocalNotification();
    await FirebaseMessaging.instance.subscribeToTopic('topic1');
    await FirebaseMessaging.instance
        .setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );
  });

  

  HttpOverrides.global = MyHttpOverrides();
 
  await setupServiceLocator();

  runApp(const MyApp());
}


class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: const Size(393, 786),
        minTextAdapt: true,
        splitScreenMode: true,
        builder: (context, child) {
          return MultiProvider(
            providers: [
              ChangeNotifierProvider(create: (context) => getIt<AuthManager>()),
              ChangeNotifierProvider(
                  create: (context) => getIt<CompanyDetailsManager>()),
              ChangeNotifierProvider(
                  create: (context) => getIt<TransactionManager>()),
              ChangeNotifierProvider(
                  create: (context) => getIt<PasswordManager>()),
              ChangeNotifierProvider(
                  create: (context) => getIt<RewardManager>()),
              ChangeNotifierProvider(
                  create: (context) => getIt<ProfileManager>()),
              ChangeNotifierProvider(
                  create: (context) => getIt<TransHistoryManager>()),
            ],
            child: MaterialApp(
                debugShowCheckedModeBanner: false,
                onGenerateRoute: Routers.generateRoute,
                navigatorKey: navigatorKey,
                initialRoute: splash),
          );
        });
  }
}

class MyHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext? context) {
    return super.createHttpClient(context)
      ..badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
  }
}

报错截图

Firebase初始化异常报错截图

问题原因及修复方案

核心问题

  1. 初始化顺序错误:你在调用runApp之后才执行Firebase初始化,且重复调用了两次Firebase.initializeApp()。同时UserInfoService中的userInfoCollection是类级别变量,会在App启动时就被初始化,此时Firebase还未就绪,直接触发异常。
  2. 依赖就绪时机不匹配:setupServiceLocator()在Firebase初始化后执行,但runApp提前启动,导致依赖可能未完全初始化。

修复步骤

  1. 调整main函数执行顺序:确保Firebase初始化完成后再启动App,且只初始化一次:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 先完成Firebase初始化,用await保证执行完成
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform, // 必须传入平台配置项
  );

  // 初始化通知相关逻辑
  FirebaseInitialization.sharedInstance.registerNotification();
  FirebaseInitialization.sharedInstance.configLocalNotification();
  await FirebaseMessaging.instance.subscribeToTopic('topic1');
  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );

  HttpOverrides.global = MyHttpOverrides();
  await setupServiceLocator();

  // 最后启动App
  runApp(const MyApp());
}
  1. 延迟初始化Firestore集合:将userInfoCollection改为延迟初始化,避免在Firebase就绪前访问:
class UserInfoService{
  // 改为late变量,在类实例化时初始化
  late CollectionReference userInfoCollection;
  UserDetails userDetails = UserDetails();

  UserInfoService(){
    userInfoCollection = FirebaseFirestore.instance.collection('userInfo');
  }

  // 或改用getter延迟加载
  // CollectionReference get userInfoCollection => FirebaseFirestore.instance.collection('userInfo');

  addData(UserDetails? userInfo) async {
    await userInfoCollection.doc(userInfo!.user!.sId).set(userInfo.toJson());
    return true;
  }


  Future<UserDetails> getInfo(String? userId)async{
    DocumentSnapshot ds = await userInfoCollection.doc(userId).get();
    if(ds.data() != null){
      return UserDetails.fromJson(ds.data() as Map<String, dynamic>);
    }
    return UserDetails();
  }

}
  1. 确认依赖注入时机:如果UserInfoService是通过service_locator注册的,确保注册逻辑在Firebase初始化之后执行,避免提前实例化。

内容的提问来源于stack exchange,提问作者Minal Suryawanshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:17:07