【问题标题】:FutureBuilder of Firebase.initializeApp() called twice with ConnectionState.doneFirebase.initializeApp() 的 FutureBuilder 使用 ConnectionState.done 调用了两次
【发布时间】:2021-10-01 08:49:18
【问题描述】:

我正在关注 FlutterFire 入门 - https://firebase.flutter.dev/docs/overview。 当我在initializing flutter fire 运行示例代码时,FutureBuilder 被调用了 3 次,第一次为 snapshot.connectionState 等待,第二次和第三次为 snapshot.connectionState 完成。 我不明白为什么用 snapshot.connectionState == ConnectionState.done 调用 FutureBuilder 两次的原因

以下是我的代码,与 FlutterFire 入门页面中的示例完全相同。

import 'package:flutter/material.dart';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';


void main() {
    WidgetsFlutterBinding.ensureInitialized();
    runApp(App());
}


class App extends StatefulWidget {

    @override
    _AppState createState() => _AppState();

}


class _AppState extends State<App> {

    final Future<FirebaseApp> _initialization = Firebase.initializeApp();

    @override
    Widget build(BuildContext context) {
        return FutureBuilder(
            future: _initialization,
            builder: (coontext, snapshot) {
                if (snapshot.hasError) {
                    Text("snapshot error. $snapshot");
                }

                if (snapshot.connectionState == ConnectionState.done) {
                    // this is printed twice!!
                    print("Initialize Firebase Done!!");
                    return MyHome();
                }

                return Loading();
            }
        );
    }

}


class Loading extends StatelessWidget {

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                body: Center(
                    child: Container(
                        child: Text("Loading..."),
                    ),
                ),
            )
        );
    }

}


class MyHome extends StatefulWidget {
        
    @override
    _MyHomeState createState() => _MyHomeState();

}


class _MyHomeState extends State {

    @override
    void initState() {
        FirebaseAuth
            .instance
            .idTokenChanges()
            .listen((User? user) {
                if (user == null) {
                    print('User is signed out');
                } else {
                    print('User is signed in!.' + user.displayName!);
                }
             });

        super.initState();
    }

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                body: Text('hello'),
            )
        );
    }

}

【问题讨论】:

  • 你好,请查看链接stackoverflow.com/a/50844913/5118503
  • @SonuKumar 谢谢你的链接。我测试了 FutureBuilder 并且我知道当 Widget build() 被称为 builderFutureBuilder 中也被称为 ConnectionState.done。如果初始化过程完成,我预计 _initialization(未来实例)会触发 builder仅一次

标签: firebase flutter


【解决方案1】:

下面的代码块运行了两次,因为 build 方法被调用了多次,因此它多次运行了您的 FutureBuilderbuilder 回调。

if (snapshot.connectionState == ConnectionState.done) {
  ...
}

来自build 方法的文档,

此方法可能会在每一帧中调用,但不应 除了构建小部件之外还有任何副作用。

https://api.flutter.dev/flutter/widgets/State/build.html

因此您的代码应该预期可以随时调用build 方法。

【讨论】:

    猜你喜欢
    • 2021-12-15
    • 2017-06-25
    • 2013-01-21
    • 2012-09-08
    • 2016-04-27
    • 2019-02-27
    • 1970-01-01
    • 2019-12-04
    • 2018-09-15
    相关资源
    最近更新 更多