Flutter Firebase 验证电话完成程序搞砸了

Posted

技术标签:

【中文标题】Flutter Firebase 验证电话完成程序搞砸了【英文标题】:Flutter Firebase Verify Phone Completer got messed up 【发布时间】:2021-09-06 23:16:35 【问题描述】:

我正在尝试使用 Firebase 验证手机。

第一次验证(第一次verifyPhoneNumberFirebase调用没问题(打开验证码,没验证按回,还是去codeSent,不知道为什么)。

但是第二次验证(第二次verifyPhoneNumberFirebase,发生在第一次验证几秒钟之后)超时,运行codeAutoRetrievalTimeout。但奇怪的是 completer 完成了,尽管它被重新启动,但前一次调用 (codeSent) 的结果。这是代码

Future<DataResponse> verifyPhoneNumberFirebase(String phoneNumb) async 
    final completer = Completer<DataResponse>(); /// <--- init and re-init
    _auth
        .verifyPhoneNumber(
      phoneNumber: phoneNumb,
      verificationCompleted: (PhoneAuthCredential credential) 
        completer.complete(successSomething(verificationId));
      ,
      verificationFailed: (FirebaseAuthException e) 
        completer.complete(errorHandling('error');
        
      ,
      codeSent: (String verificationId, int resendToken) 
        completer.complete(successSomething(verificationId)); 
         /// the first complete, 
         /// and somehow the second complete, 
         /// even though it did not go to this line in the second call
      ,
      codeAutoRetrievalTimeout: (String verificationId) 
        completer.complete(errorHandling('error'); /// <----- already completed ???
      ,
    );
    return completer.future;
  

这里是日志

[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Bad state: Future already completed
_AsyncCompleter.complete (dart:async/future_impl.dart:45:31)
...

现在我不知道如何获得codeAutoRetrievalTimeout 输出。

【问题讨论】:

【参考方案1】:

之所以出现错误,是因为您在 verificationCompleted 回调中使用了 Completer,而它已在 codeSent 回调中使用。

您可以从codeSent 块中删除completer.complete,因为此时它还没有完成操作。

以下是您的 _auth.verifyPhoneNumber 代码的更新:

     _auth
            .verifyPhoneNumber(
          phoneNumber: phoneNumb,
          verificationCompleted: (PhoneAuthCredential credential) 
            completer.complete(successSomething(verificationId));
          ,
          verificationFailed: (FirebaseAuthException e) 
            completer.complete(errorHandling('error');
            
          ,
          codeSent: (String verificationId, int resendToken) 
            successSomething(verificationId); // Remove completer.complete
          ,
          codeAutoRetrievalTimeout: (String verificationId) 
            completer.complete(errorHandling('error'); 
          ,
        );

【讨论】:

啊,是的,我刚刚意识到第一个电话也是电话codeAutoRetrievalTimeout。所以这就引出了第二个问题:为什么第二次调用没有调用任何回调?也许是因为扑火? 我没有完全得到第二个问题。需要注意的一点是,在完成操作时应该使用完成器。 啊是的,事情就是这样。在我调用了这个函数之后,我再次调用了它(在它可以进入codeAutoRetrievalTimeout之前)。之后什么也没发生。它超出了最初的问题,但这正是我在这里真正想问的。 您能否创建一个新问题来详细描述这一点,尤其是您两次调用该函数并将链接放在这里以便我查看的部分? 我想我会把它留给 Flutterfire 团队。我找到了避免它的方法(不确定它是否正常工作)。

以上是关于Flutter Firebase 验证电话完成程序搞砸了的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 身份验证 Flutter 中的电话号码

Firebase 电话身份验证 (Flutter) 在某些 iOS 设备中不起作用

我正在使用 firebase flutter 实现电话身份验证。但是有一个问题

在 Flutter 中使用 Firebase 电话身份验证超时后使 OTP 无效

Flutter + Firebase Auth:有啥方法可以在 Web 上使用 Firebase 电话身份验证重新发送短信验证码?

Firebase (Flutter) 验证电话号码始终需要 reCAPTCHA