首页 > 解决方案 > FirebaseAuth.instance.verifyPhoneNumber 无法正常工作 - Flutter

问题描述

await FirebaseAuth.instance.verifyPhoneNumberawait FirebaseAuth.instance.verifyPhoneNumber从某种意义上说,在成功执行之前运行的代码无法正常工作。await并没有真正做好它的工作。

为了便于理解问题,我不会分享所有代码,只分享相关代码。我有一个名为的视图CustRegView,我从用户那里获取电话号码并将其发送到名为 进行身份验证的ViewModelCustRegViewModel,该视图应该根据其身份验证返回真或假。

下面是视图的样子

class CustRegView extends StatelessWidget{
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final deviceSize = MediaQuery.of(context).size;
    return BaseView<CustRegViewModel>( 
          builder: (context, model, child) => Scaffold(
    
    ...<some code>
    
    TextFeild( controller: _controller, ...<some code> )

    ...<some code>
    
    FlatButton (
        onPressed: () async {
            var registerSuccess = await model.register( _controller.text, context);
                                
            if (registerSuccess) {
                Navigator.pushNamed(context, 'newScreen');
            } else {
                UIHelper().showErrorButtomSheet(context, model.errorMessage);
            }
    )
}

下面是现在Viewmodel 的样子

class CustRegViewModel extends BaseViewModel {
    
    final AuthService _authService = locator<AuthService>();
    final DialogService _dialogService = locator<DialogService>();
    dynamic newUserResult;    <----  It will hold the authentication result value. IT'S VALUE SHOULD CHANGE FROM INSIDE "codeSent" FUNCTION OR "verificationCompleted" FUNCTION BUT IT IS NOT CHANGING

    Future<bool> register(String phoneNo, BuildContext context) async {
        print("Register function of viewModel is reached");
        setState(ViewState.Busy);
    
        await verifyPhone;

        if(newUserResult  !=  null){ 
            print("Returning true" )
            return true; 
        } else {    
            print("Returning false")
            return false;
        }
    }

    Future<void> verifyPhone(phoneNo) async {

        String smsCode;
        Future<String> getOTPresult() async { ...<some code> }

            print("VerifyFunction  is reached");
      
            await FirebaseAuth.instance.verifyPhoneNumber(
                    phoneNumber: updatedPhoneNo,
                    timeout: Duration(seconds: 50),
            verificationCompleted: (AuthCredential authCred) async {...... <some code>
                    verificationFailed: (AuthException authException) {...... <some code>
                    codeSent: (String verID, [int forceCodeResend]) async {
          
                        print(" --------------> Code sent reached. Will update newUserResult on success ");
                var OTPDialogResult = await getOTPresult();
                AuthCredential authCred = PhoneAuthProvider.getCredential( verificationId: verID, smsCode: OTPDialogResult);            
                newUserResult =  AuthService().signInWithPhoneNumber(authCred);
                     },
                    codeAutoRetrievalTimeout: (String verID) {...

            ).catchError((error) {...... <some code>
      
            print( "Automatically returning null");

    }
}

在这里,所需的输出在控制台上应该是这样的

Register function of viewModel is reached
VerifyFunction  is reached
--------------> Code sent reached. Will update newUserResult on success 
Returning true 

在达到 CustRegViewModel 注册函数时,我得到这样的输出,发送的代码在返回 false 后到达

Register function of viewModel is reached
VerifyFunction  is reached
Automatically returning null
Returning false

--------------> Code sent reached. Will update newUserResult on success

标签: firebaseflutterdartfirebase-authentication

解决方案


我实际上已经通过简单地使用completer. 现在函数不会自动返回 null。Completer等待verifyPhoneNumber方法的整个执行并返回truefalse基于所需的结果。我是这样用的。

  Future<bool> verifyPhone(phoneNo) async {

    var completer = Completer<bool>();

            await FirebaseAuth.instance.verifyPhoneNumber(
                    phoneNumber: updatedPhoneNo,
                    timeout: Duration(seconds: 50),
                    verificationCompleted: (AuthCredential authCred) async {
                                ....<some code>
                               
                                completer.complete(true);

                     }
                    verificationFailed: (AuthException authException) {...... <some code>
                    codeSent: (String verID, [int forceCodeResend]) async {...... <some code>
                    codeAutoRetrievalTimeout: (String verID) {...
             ).catchError((error) {...... <some code>
       
      return completer.future;
}

推荐阅读