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; } }
报错截图

问题原因及修复方案
核心问题
- 初始化顺序错误:你在调用
runApp之后才执行Firebase初始化,且重复调用了两次Firebase.initializeApp()。同时UserInfoService中的userInfoCollection是类级别变量,会在App启动时就被初始化,此时Firebase还未就绪,直接触发异常。 - 依赖就绪时机不匹配:
setupServiceLocator()在Firebase初始化后执行,但runApp提前启动,导致依赖可能未完全初始化。
修复步骤
- 调整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()); }
- 延迟初始化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(); } }
- 确认依赖注入时机:如果
UserInfoService是通过service_locator注册的,确保注册逻辑在Firebase初始化之后执行,避免提前实例化。
内容的提问来源于stack exchange,提问作者Minal Suryawanshi
相关产品推荐
相关产品推荐

