flutter - Flutter 中的异步函数未返回预期数据

标签 flutter dart async-await firebase-authentication

我正在尝试使用 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),
即使函数本身是异步的,也不会等待

。那么会发生什么:

  1. verifyUserPhoneNumber 从某处调用
  2. FirebaseAuth.instance.verifyPhoneNumber 正在等待
  3. 在此调用中,将调用 verificationComplete(credential),并且由于它本身包含一个等待语句,因此它将由 Dart 事件循环排队。因此,无论 FirebaseUser user = wait FirebaseAuth.instance.currentUser(); 之后发生的事情都会被延迟!
  4. verifyUserPhoneNumber 现在继续执行并返回 false
  5. 返回值后,现在轮到 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/

相关文章:

flutter - 如何在Flutter中使用本地JSON在我的应用程序中动态创建页面?

flutter - 如何根据 flutter 中屏幕的分数高度在堆栈内定位列?

Flutter ExpansionPanelList - expansionCallback 不工作

dart - Dart polymer 变压器到JS问题

javascript - 为什么 async/await 会产生不同的结果

javascript - 我如何从 mongodb 数据库获取所有文档?

flutter - flutter 的文本在右侧溢出

http - 来自 http post 请求的响应在中间被切断

dart - 我可以将 ng-if 指令放在也绑定(bind)到 Controller 的元素上吗

javascript - try/catch 中的异步/等待在等待解决后未显示处理逻辑中的错误