是否有负面的后果调用Firebase initializeApp()两次?



虽然Firebase.initializeApp()只需要调用一次,但调用两次是否会产生负面后果?

背景:我正在排除[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()错误,并通过添加await Firebase.initializeApp();在void main()异步除了我已有的final Future<FirebaseApp> _fbApp = Firebase.initializeApp();

现在一切似乎都正常了。我打算修复它,但如果两次调用Firebase.initializeApp()没有伤害任何东西,我可以坚持我的当前优先级并继续前进。

下面是相关的代码块:

void main() async {
WidgetsFlutterBinding
.ensureInitialized(); // added per https://stackoverflow.com/questions/57689492/flutter-unhandled-exception-servicesbinding-defaultbinarymessenger-was-accesse
await Firebase
.initializeApp(); 
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final Future<FirebaseApp> _fbApp = Firebase
.initializeApp(); // changed from "async {  await Firebase.initializeApp();" per official "Getting started with Firebase on Flutter - Firecasts" video at https://youtu.be/EXp0gq9kGxI?t=920
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return StreamProvider<Userrr>.value(
value: AuthService().user,
// above specifies what stream we want to listen to and what data we expect to get back
child: MaterialApp(

谢谢!

我试了下面所有的好建议,但似乎都不起作用。我认为我的代码是两个教程(一个用于Firebase入门,另一个用于Firebase auth 101)的精确复制,由于包更新或其他不兼容性,有一个或多个空白。

我回到基础,手工编写,并重新实现安装和设置Firebase Core的每个步骤,从官方的"FlutterFire概述"。

按照下面的建议,我重新阅读了所有的文档。

我更新了所有的包,包括firebase_auth: " ^0.20.0"到firebase_auth: " ^0.20.0+1"(根据更改日志,+1更改是"FIX: package compatibility")。

最后,我创建了main的备份。Dart为old_main。dart,然后复制粘贴精确的"初始化flutterfire"futurebuilder代码,然后小心地将泛型代码的每个部分替换为我自己的代码。以下是我替换的条目:

// replaced "_initialization" with "_fbApp"
// replaced if (snapshot.hasError) ... "return SomethingWentWrong();" with the response from below
// replaced "return Loading();" with CircularProgressIndicator form below
// changed return MyAwesomeApp(); to return MyApp();
// changed "class App extends StatelessWidget" to "class MyApp extends StatelessWidget
// replaced "MyAwesomeApp();" from "if (snapshot.connectionState == ConnectionState.done) { return MyAwesomeApp();" with all the "StreamProvider<Userrr>.value(..." code EXCEPT changed home to "home: Wrapper(),"

这可能看起来很简单,但对于像我这样的新手来说,这是唯一的前进之路。谢天谢地,它起作用了!

下面是完整的工作代码摘录:

void main() {
WidgetsFlutterBinding
.ensureInitialized(); // added by mgav, per https://stackoverflow.com/questions/57689492/flutter-unhandled-exception-servicesbinding-defaultbinarymessenger-was-accesse
// await Firebase.initializeApp(); // added by mgav to test, KNOWING the Firebase is already initialized as a future below in line 25. Was trying to test (temp?) fix for error: “[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()  The relevant error-causing widget was:  MyApp file:///Users/mgav/AndroidStudioProjects/brand_new_flutter_app/lib/main.dart:21:10”
runApp(MyApp());
}
// BEGIN Firebase FutureBuilder code pasted from docs at https://firebase.flutter.dev/docs/overview/#initializing-flutterfire (replaces next section of commented-out code)
class MyApp extends StatelessWidget {
// Create the initialization Future outside of `build`:
final Future<FirebaseApp> _fbApp = Firebase.initializeApp();
@override
Widget build(BuildContext context) {
return FutureBuilder(
// Initialize FlutterFire:
future: _fbApp,
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
print('You have an error! ${snapshot.error.toString()}');
return Text('Something went wrong main.dart around line 48');
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
return StreamProvider<Userrr>.value(
value: AuthService().user,
// above specifies what stream we want to listen to and what data we expect to get back
child: MaterialApp(
title: 'Real Revs and Q&A',
theme: ThemeData(
primarySwatch: Colors.blueGrey,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routes: {
// '/welcome': (context) => WelcomeScreen(),
'/cleanwritereview': (context) => CleanWriteReviewScreen(),
'/registrationscreen': (context) => RegistrationScreen(),
'/loginscreen': (context) => LoginScreen(),
'/viewreviewsscreen': (context) => ViewReviewsScreen(),
'/homescreen': (context) => Home(),
},
home: Wrapper(),
),
);
}
// Otherwise, show something whilst waiting for initialization to complete
return Center(
child: CircularProgressIndicator(),
);
},
);
}
}

如果对同一个FirebaseApp调用initializeApp()两次,将得到错误消息。

在您的例子中,您可以获取你已经用:

创建的应用
final FirebaseApp _fbApp = Firebase.app();

请参阅有关FlutterFire的文档,特别是初始化和使用FirebaseApp。

初始化firebase:

main(){
await Firebase.initializeApp(); // don't run the app until firebase is initialized
runApp(MyApp());
}

或者使用FutureBuilder来确保在运行构建器函数内的代码之前解决未来。

@override
Widget build(BuildContext context) {
final _fbApp = Firebase.initializeApp();
return FutureBuilder(
future: _fbApp, 
builder: (context, snapshot) { // waits until _fbApp is resolved to execute.
.... 
});
}

你得到一个错误,因为你没有等待_fbApp的未来。

在你的代码中,不能保证在initializeApp完成后执行AuthService().user。为了保证这一点,你必须等待,直到initializeApp()通过await被解析,然后使用FutureBuilder。

添加一个try catch来理解为什么initializeApp中的第一个调用不工作

Firebase只初始化其核心服务一次。按名称只有一个FirebaseApp实例。当您没有指定名称时,使用'[DEFAULT]'。

试试这样做:

final app = await Firebase.initializeApp();
final app2 = await Firebase.initializeApp();
print(app == app2); // is true

请提供更多关于您的设置的详细信息:

  • firebase_auth, firebase_core版本,
  • 执行平台(Android, ios或web)。

在fire_auth的最后一个版本中,我们使用:

FirebaseAuth.instance.authStateChanges // stream to subscribe to the user's current authentication state.

最新更新