flutter - 颤动中的异步执行问题
问题描述
在下面的代码中,在第 18 行执行时调用了未来函数 readData() 并在其完成执行之前移至第 19 行,即打印语句。我想在调用 readData() 函数后等待函数完成执行并更新标志变量,然后在移动后进一步执行
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/cupertino.dart';
import 'package:udharibook/Screens/SignInPage.dart';
import 'package:udharibook/Screens/UserProfile.dart';
import 'package:udharibook/Screens/dashboard.dart';
class AuthService {
bool flag = false;
final FirebaseAuth _auth = FirebaseAuth.instance;
final DBRef = FirebaseDatabase.instance.reference().child('Users');
handleAuth(){
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext, snapshot) {
if(snapshot.hasData) {
readData();
print(flag);
if(flag ==true)
return DashboardPage();
else
return UserProfile();
}
else {
return SignIn();
}
},
);
}
Future<void> readData() async {
final FirebaseUser user = await _auth.currentUser();
final userid = user.uid;
DBRef.child(userid).once().then((DataSnapshot data){
print(userid);
if(data.value!=null)
{
flag = true;
print(data.key);
print(data.value);
}
else{
print('User not found');
flag = false;
}
});
}
signOut(){
FirebaseAuth.instance.signOut();
}
signIn(AuthCredential authCreds){
FirebaseAuth.instance.signInWithCredential(authCreds);
}
signInWithOTP(smsCode,verId){
AuthCredential authCreds = PhoneAuthProvider.getCredential(
verificationId: verId,
smsCode: smsCode
);
signIn(authCreds);
}
}
解决方案
使用 FutureBuilder 并让您readData
返回 true 或 false 而不是设置变量。
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext, snapshot) {
if(snapshot.hasData) {
return FutureBuilder<String>(
future: readData(),
builder: (BuildContext context, AsyncSnapshot<String> readDataSnapshot) {
//readDataSnapshot.data will be your true/false from readData()
if(readDataSnapshot.hasData){
if(readDataSnapshot.data == true)
return DashboardPage();
else
return UserProfile();
} else {
return CircularProgressIndicator(); // or something else while waiting for the future to complete.
}
}
);
} else {
return SignIn();
}
},
);
Future<bool> readData() async {
final FirebaseUser user = await _auth.currentUser();
final userid = user.uid;
DBRef.child(userid).once().then((DataSnapshot data){
print(userid);
if(data.value!=null)
{
print(data.key);
print(data.value);
return true;
}
else{
print('User not found');
return false;
}
});
}
推荐阅读
- javascript - 如何在“find()”的结果中找到一个元素?
- python - Python Asyncio 帮助....我这样做对吗?
- c++ - 如何在纯 c++ 环境中使用 qt 中的图像?
- python - 在 Python 中的 asyncio 任务上拦截对 __await__ 的调用
- python - Pandas 数据框列匹配和分组依据
- python - 文本数据预处理的正确步骤是什么
- javascript - Node.js 上的 Minecraft 机器人
- java - Jersey 和 Springboot 应用程序抛出 java.lang.StackOverflowError
- verilog - 警告:实例化深度可能表示 ModelSim 中的递归
- php - php - 将选中的属性添加到匹配的下拉选项中