我正在尝试使用 firebase 验证电话号码。但从异步函数中得到了意想不到的结果。这是我的代码:
bool isVerificationSuccess = false;
Future<bool> verifyUserPhoneNumber(String phoneNumber) async {
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: 60),
verificationCompleted: (credential) => verificationComplete(credential),
verificationFailed: (authException) => verificationFailed(authException),
codeAutoRetrievalTimeout: (verificationId) =>
codeAutoRetrievalTimeout(verificationId),
codeSent: (verificationId, [code]) => smsCodeSent(verificationId, [code]),
);
print("Status from service : $isVerificationSuccess");
return isVerificationSuccess;
}
verificationComplete(AuthCredential credential) async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
user.linkWithCredential(credential).then((_) {
print("User Successfully Linked");
isVerificationSuccess = true;
}).catchError((e) {
print("Linking Error : ${e.toString()}");
});
}
这是输出:
Status from service : false
User Successfully Linked
因此,这里 verifyUserPhoneNumber
函数甚至在 FirebaseAuth.instance.verifyPhoneNumber()
完成之前就返回,因此它不会返回预期数据(始终 false
>) 即使验证成功。这里出了什么问题?
最佳答案
问题在于这一行中的函数调用:
verificationCompleted: (credential) => verificationComplete(credential),
即使函数本身是异步的,也不会等待 。那么会发生什么:
verifyUserPhoneNumber
从某处调用FirebaseAuth.instance.verifyPhoneNumber
正在等待- 在此调用中,将调用
verificationComplete(credential)
,并且由于它本身包含一个等待语句,因此它将由 Dart 事件循环排队。因此,无论FirebaseUser user = wait FirebaseAuth.instance.currentUser();
之后发生的事情都会被延迟! verifyUserPhoneNumber
现在继续执行并返回false
。- 返回值后,现在轮到
verificationComplete
进行处理。它将更改 bool 值,然后退出。
我在这里的建议是不要使用全局变量,而是,例如,在 FirebaseAuth.instance.verifyPhoneNumber
之后调用 verificationComplete
after已完全处理完毕并返回。
编辑:这就是理论上解决问题的方法,尽管我承认它不是特别漂亮:
Future<bool> verifyUserPhoneNumber(String phoneNumber) async {
final completer = Completer<AuthCredential>();
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: 60),
verificationCompleted: completer.complete,
verificationFailed: completer.completeError,
codeAutoRetrievalTimeout: (verificationId) =>
codeAutoRetrievalTimeout(verificationId),
codeSent: (verificationId, [code]) => smsCodeSent(verificationId, [code]),
);
try {
final credential = await completer.future;
return await verificationComplete(credential);
} catch (e) {
verificationFailed(e);
return false;
}
}
Future<bool> verificationComplete(AuthCredential credential) async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
try {
await user.linkWithCredential(credential);
print("User Successfully Linked");
return true;
} catch (e) {
print("Linking Error : ${e.toString()}");
return false;
}
}
关于flutter - Flutter 中的异步函数未返回预期数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60868127/