在 Flutter 的流构建器中使用 Future 构建器是正确的

3 dart firebase-authentication flutter google-cloud-firestore

我的要求是,每当用户使用电话号码验证时,它都会在 Firebase 中检查之前登录的用户电话号码设置的文档 ID 是否存在(如果存在),然后转到主页(如果不存在),然后导航到帐户验证页面。

另外如果用户已经登录但没有验证关闭应用程序然后再打开应用程序则有两种情况首先用户已验证帐户详细信息或在验证过程中尚未验证。在这种情况下,我将检查设置为用户电话号码的文档 ID 是否存在(如果存在),然后转到主页或 AccountVerification 页面。这是我的代码,但运行不完美。谁能建议我什么才是正确的方法

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  var globalNumber;
  var Number;
  Firestore firestore = Firestore.instance;


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getCurrentUser();



  }

  @override
  Widget build(BuildContext context) {
    print(globalNumber);
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: StreamBuilder<Object>(
        stream: FirebaseAuth.instance.onAuthStateChanged,
          builder: (BuildContext context, snapshot) {
            if (snapshot.hasData) {
              return FutureBuilder(
                  future: Future.wait([

                    firestore.collection('users').document(globalNumber).get()

                  ]),
                  builder: (BuildContext context,
                      AsyncSnapshot<List> snapshot) {
                    DocumentSnapshot doc = snapshot.data[0];
                    if(snapshot.hasData) {
                      if (doc.exists) {
                        return HomePage();
                      }
                      return AccountDetialsPage();
                    }
                    else{
                      return Container(child: Text('Loading'));
                    }
                  }
              );
            } else {
              return Phoneverification();
            }
          }),
    ) ;
  }

  getCurrentUser() async{

    final FirebaseAuth _auth = FirebaseAuth.instance;
    final FirebaseUser user = await _auth.currentUser();
    final uid = user.uid;
    globalNumber = user.phoneNumber;
    
    // Similarly we can get email as well
    //final uemail = user.email;
    print(uid);

  }

}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ira 6

它无法正常工作,正如记录的那样:

\n
\n

\xe2\x80\x9c 未来必须已提前获得,例如在 State.initState、State.didUpdateConfig 或 State.didChangeDependency 期间。在构造 FutureBuilder 时,不得在 State.build 或 StatelessWidget.buildmethod 调用期间创建它。如果 future 与 FutureBuilder 同时创建,则每次重建 FutureBuilder 的父级时,异步任务都会重新启动。\xe2\x80\x9d

\n
\n

这意味着当您未来的方法返回一个值时,就会发生重建,从而触发另一次重建。这就形成了一个循环。

\n

您应该调用 future 函数initState(),然后使用该变量在 build 方法中使用 FutureBuilder。例如:

\n
    void main() {\n      runApp(MyApp());\n    }\n\n    class MyApp extends StatefulWidget {\n      @override\n      _MyAppState createState() => _MyAppState();\n    }\n\n    class _MyAppState extends State<MyApp> {\n\n      var globalNumber;\n      var Number;\n      var user;\n      Firestore firestore = Firestore.instance;\n\n\n      @override\n      void initState(){\n         super.initState();\n         getCurrentUser();\n      }\n\n\n      Widget build(BuildContext context){\n        return return MaterialApp(\n        debugShowCheckedModeBanner: false,\n        home: StreamBuilder<Object>(\n          stream: FirebaseAuth.instance.onAuthStateChanged,\n          builder: (BuildContext context, snapshot) {\n            if (snapshot.hasData) {\n              return FutureBuilder(\n                  future: user,\n                  builder: (BuildContext context,\n                      AsyncSnapshot<List> snapshot) {\n                    DocumentSnapshot doc = snapshot.data[0];\n                    if(snapshot.hasData) {\n                      if (doc.exists) {\n                        return HomePage();\n                      }\n                      return AccountDetialsPage();\n                    }\n                    else{\n                      return Container(child: Text(\'Loading\'));\n                    }\n                  }\n              );\n            } else {\n              return Phoneverification();\n            }\n        }),\n      );\n    }\n\n    getCurrentUser() async{\n\n      final FirebaseAuth _auth = FirebaseAuth.instance;\n      final FirebaseUser user = await _auth.currentUser();\n      final uid = user.uid;\n      globalNumber = user.phoneNumber;\n    \n      // Similarly we can get email as well\n      //final uemail = user.email;\n      print(uid);\n    \n      getUserNumber(uid);\n    }\n\n    //Make another function that you insert into the getCurrentUser(), like this:\n    \n    getUserNumber(int uid){\n      user = Future.wait([\n      firestore.collection(\'users\').document(globalNumber).get()\n    ]);\n  }\n
Run Code Online (Sandbox Code Playgroud)\n