FlutterFire Auth:verifyPhoneNumber未等待完成致空检查异常
解决Firebase短信验证中无法正确返回verificationId的问题
你的问题核心在于:FirebaseAuth.instance.verifyPhoneNumber()的Future会在验证流程初始化完成后就结束,而非等到codeSent或verificationCompleted回调触发后才完成。所以你用await等待这个Future结束时,回调里的result还没被赋值,直接返回result!就会触发空检查异常。从终端输出也能看出来:先打印了This is the result null,之后才打印ver_id <ver_id>,说明回调是在方法返回之后才执行的。
解决方案:使用Completer手动控制Future的完成时机
我们可以用dart:async里的Completer来创建一个自定义Future,只有当我们拿到verificationId或者遇到错误时,才让这个Future完成。修改后的代码如下:
import 'dart:async'; import 'package:firebase_auth/firebase_auth.dart'; Future<String> sendPhoneVerification({ required String phoneNumber, }) { final completer = Completer<String>(); FirebaseAuth.instance.verifyPhoneNumber( phoneNumber: '+1$phoneNumber', verificationCompleted: (PhoneAuthCredential credential) { completer.complete(credential.verificationId); }, verificationFailed: (e) { Exception exception; if (e.code == 'invalid-phone-number') { exception = InvalidPhoneNumberAuthException(); } else if (e.code == 'too-many-requests') { exception = TooManyRequestsAuthException(); } else { exception = GenericAuthException(); } completer.completeError(exception); }, codeSent: (verificationId, resendToken) { print('ver_id $verificationId'); completer.complete(verificationId); }, codeAutoRetrievalTimeout: (_) {}, ); return completer.future; }
代码说明
- 创建
Completer<String>实例,它可以帮我们生成一个可控的Future<String> - 在
verificationCompleted和codeSent回调中,调用completer.complete(verificationId),把拿到的验证ID传递出去,标记Future完成 - 在
verificationFailed回调中,调用completer.completeError(exception),把自定义异常抛出,外部调用时可以用try-catch捕获 - 最后返回
completer.future,外部调用这个方法时,会等待到verificationId生成或者异常抛出才会继续执行
这样修改后,你的方法就会正确等待到verificationId生成后再返回,不会出现空值异常。
内容的提问来源于stack exchange,提问作者random person
相关产品推荐
相关产品推荐

