在 Flutter 的流构建器中使用 Future 构建器是正确的
Posted
技术标签:
【中文标题】在 Flutter 的流构建器中使用 Future 构建器是正确的【英文标题】:Is is correct to use Future builder inside a streambuilder in Flutter 【发布时间】:2020-11-26 22:34:31 【问题描述】:我的要求是,每当用户使用电话号码进行验证时,它都会在 Firebase 中检查设置为用户电话号码的文档 ID(如果之前登录过)是否存在,如果存在则转到主页然后不会导航到 AccountVerification 页面。
另外,如果用户已经登录但没有验证关闭应用再打开应用,那么有两种情况,一种是用户验证了帐户详细信息,或者在验证过程中没有验证。在这种情况下,我将检查设置为用户电话号码的文档 ID 是否存在(如果存在),然后转到 HomePage 否则 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);
【问题讨论】:
我的评论解决了你的问题吗?我正在寻找一些反馈,因为我刚开始在 *** 上帮助其他人! 您好,我已经将答案标记为正确......是的,它有帮助......非常感谢 【参考方案1】:它不能正常工作,正如它所记录的那样:
“未来一定是更早获得的,例如在 State.initState、State.didUpdateConfig 或 State.didChangeDependencies 期间。在构造 FutureBuilder 时,不能在 State.build 或 StatelessWidget.buildmethod 调用期间创建它。如果 Future 与 FutureBuilder 是同时创建的,那么每次 FutureBuilder 的 parent 重建时,异步任务都会重新启动。”
这意味着当你的未来方法返回一个值时,会发生重建,触发另一个重建。这会创建一个循环。
您应该在initState()
上调用您的未来函数,然后使用该变量在构建方法中使用 FutureBuilder。例如:
void main()
runApp(MyApp());
class MyApp extends StatefulWidget
@override
_MyAppState createState() => _MyAppState();
class _MyAppState extends State<MyApp>
var globalNumber;
var Number;
var user;
Firestore firestore = Firestore.instance;
@override
void initState()
super.initState();
getCurrentUser();
Widget build(BuildContext context)
return return MaterialApp(
debugShowCheckedModeBanner: false,
home: StreamBuilder<Object>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, snapshot)
if (snapshot.hasData)
return FutureBuilder(
future: user,
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);
getUserNumber(uid);
//Make another function that you insert into the getCurrentUser(), like this:
getUserNumber(int uid)
user = Future.wait([
firestore.collection('users').document(globalNumber).get()
]);
【讨论】:
我对 Flutter 完全不熟悉......你能告诉我代码吗......我被困在这个页面上 对不起,发布时没有进一步的代码编辑。看看这是否能解决您的问题。 @override void initState() super.initState(); x = Future.wait([ firestore.collection('users').document(globalNumber).get() ]); .... 这里当调用 init 函数时,我还没有 globalNumber,因为在我之前在 init 函数中的代码中,我调用了获取当前用户,然后从那里获取了用户号......如何解决我的意思是,当应用程序启动时,会调用 init 并且该数字尚未分配给 globalNumber 变量......另外,未来的“x”数据类型应该是什么?????? 更新了答案,以便您可以链接这两个事件。现在,您从 Future.await() 获得的值存储在一个类变量中。 类似于 user13891541:initState 不是异步函数。所以你的意思是在 initState 中获得未来并在构建期间提供未来?我意识到我想潜在地将提供未来的函数转换为 Stream,因为如果返回值发生变化,我希望状态发生变化以上是关于在 Flutter 的流构建器中使用 Future 构建器是正确的的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Dart 中提供 Future<String> 来流式传输需要 String 的流? [复制]