Flutter开发问题:Dart callback方法未返回变量最新值如何解决
问题根因
FirebaseAuth.instance.verifyPhoneNumber 返回的Future并不会等待codeSent回调执行完成才结束,它仅在验证请求成功提交到Firebase服务端后就会直接完成。codeSent回调是Firebase服务端确认手机号合法、实际下发验证码后才会异步触发,所以你在await verifyPhoneNumber之后直接读取codeSent变量时,回调还未执行,拿到的自然是初始值false。
你日志的打印顺序(先打印false再打印inside: true)也完全符合这个执行逻辑。
解决方案
方案1:用Completer手动控制Future返回时机
这是最贴合你当前代码写法的方案,通过Completer让signInWithPhone方法等待回调触发后再返回结果:
import 'dart:async'; // 需要导入Completer所在的包 class Authenticate { Future<bool> signInWithPhone(String phone, BuildContext context) async { final Completer<bool> completer = Completer<bool>(); await FirebaseAuth.instance.verifyPhoneNumber( phoneNumber: phone, codeSent: (String verificationId, int? resendToken) { print('inside: true'); // 验证码下发成功,返回true completer.complete(true); }, verificationFailed: (FirebaseAuthException e) { // 验证失败,返回false print('验证失败:$e'); completer.complete(false); }, verificationCompleted: (PhoneAuthCredential credential) { // 手机号自动验证成功场景,按需返回结果 completer.complete(true); }, codeAutoRetrievalTimeout: (String verificationId) { // 验证码自动拉取超时场景,按需返回结果 completer.complete(false); }, ); // 等待回调触发后再返回结果 return completer.future; } }
修改后你Widget侧的原有调用逻辑不需要改动,then里拿到的result就会和回调内的变量值一致,setState后UI会正常更新。
方案2:状态监听实现UI响应
如果你的业务需要处理多种验证状态(自动填充、验证失败、超时等),可以用ValueNotifier暴露状态变化,Widget侧直接监听更新:
首先修改Authenticate类:
class Authenticate { // 暴露验证码发送状态的监听对象 final ValueNotifier<bool> codeSent = ValueNotifier(false); Future<void> signInWithPhone(String phone, BuildContext context) async { // 每次调用重置状态 codeSent.value = false; await FirebaseAuth.instance.verifyPhoneNumber( phoneNumber: phone, codeSent: (String verificationId, int? resendToken) { print('inside: true'); codeSent.value = true; }, // 其他回调按需修改codeSent的值即可 ); } }
Widget侧用ValueListenableBuilder监听状态自动更新UI:
Authenticate auth = Authenticate(); @override Widget build(BuildContext context) { return ValueListenableBuilder<bool>( valueListenable: auth.codeSent, builder: (context, isCodeSent, child) { return Column( children: [ ElevatedButton( onPressed: () => auth.signInWithPhone(phone, context), child: const Text('Verify'), ), // 验证码发送成功后展示输入框等组件 if (isCodeSent) const Text('请输入收到的验证码'), ], ); }, ); }
内容的提问来源于stack exchange,提问作者Sumchans
相关产品推荐
相关产品推荐

