【问题标题】:Using FirebaseAuth verifyPhoneNumber in flutter?在颤动中使用 FirebaseAuth verifyPhoneNumber?
【发布时间】:2021-06-03 12:58:47
【问题描述】:

嘿,我正在尝试在 Flutter 中使用 Firebase Auth verifyPhoneNumber

我经常将onTap 中的msg 函数设为null。我尝试在 registerToFb 函数中声明一个变量,但我无法更新它的值。我该如何解决?

以下是我调用 firebaseAuth.verifyPhoneNymber() 方法的函数。

onTap: () async {
       setState(() => isLoading = true);
       String msg = await _auth.registerToFb(
        "+91$truephoneNumber", context);
       print(msg);

    },

以下是我定义我的功能的地方。

class AuthenticationService {
  final FirebaseAuth _firebaseAuth;

  AuthenticationService(this._firebaseAuth);

  Future registerToFb(String phoneNumber, BuildContext context) async {
    String result = " ";
    await _firebaseAuth.verifyPhoneNumber(
      phoneNumber: phoneNumber,
      timeout: const Duration(seconds: 30),
      verificationCompleted: (PhoneAuthCredential credential) async {
        UserCredential authresult =
            await _firebaseAuth.signInWithCredential(credential);

        User user = authresult.user;
        _getUserFromFirebase(user);
        result =  "signedUp";
      },
      verificationFailed: (FirebaseAuthException e) {
        String error = e.code == 'invalid-phone-number'
            ? "Invalid number. Enter again."
            : "Can Not Login Now. Please try again.";
        result = error;
      },
      codeSent: (String verificationId, int resendToken) {
       
        result = "verified";
      },
      codeAutoRetrievalTimeout: (String verificationId) {},
    );
  }
  return result;
}

请帮帮我。谢谢

【问题讨论】:

  • 我想你也想返回错误,这样可以解决吗?
  • 你没有从registerToFb返回任何东西。您所拥有的 return 位指的是闭包函数,而不是 registerToFb 函数。
  • @lrsvmb 感谢您的建议并对错误表示歉意。我忘了在那里使用return。但即使有`return error`它也不起作用。
  • Abion47 我尝试从函数返回错误值,但仍然无法正常工作

标签: flutter dart firebase-authentication


【解决方案1】:

问题是您没有在函数中返回任何内容。即使您尝试从回调内部保存值,verifyPhoneNumber 的未来也会在这些回调被调用之前解析。

你需要等待正确的事情。你不应该等待从verifyPhoneNumber 返回的未来。您应该等待一个无法解决的新未来,直到您从其中一个回调中获得结果。这意味着您需要创建自己的Future,您可以在需要时专门手动解决它。您可以使用Completer

Future<String> registerToFb(String phoneNumber, BuildContext context) {
  final completer = Completer<String>();

  _firebaseAuth.verifyPhoneNumber(
    phoneNumber: phoneNumber,
    timeout: const Duration(seconds: 30),
    verificationCompleted: (PhoneAuthCredential credential) async {
      UserCredential authresult =
          await _firebaseAuth.signInWithCredential(credential);

      User user = authresult.user;
      _getUserFromFirebase(user);
      completer.complete("signedUp");
    },
    verificationFailed: (FirebaseAuthException e) {
      String error = e.code == 'invalid-phone-number'
          ? "Invalid number. Enter again."
          : "Can Not Login Now. Please try again.";
      completer.complete(error);
    },
    codeSent: (String verificationId, int resendToken) {
      completer.complete("verified");
    },
    codeAutoRetrievalTimeout: (String verificationId) {
      completer.complete("timeout");
    },
  );

  return completer.future;
}

【讨论】:

  • 我对@9​​87654326@ 的测试表明,即使已经调用了为codeSent 提供的函数,也可以调用为codeAutoRetrievalTimeout 提供的函数。对于您的代码,这意味着 complete 可以调用两次,并且文档说“调用 [complete] 或 [completeError] 必须最多执行一次。”不知道接下来会发生什么,但我想这将以异常结束。
  • @mic 这种行为很奇怪,我怀疑这是 Firebase 包中的错误。不过,您是对的,因为在已完成的Completer 上调用complete 会导致错误,特别是带有消息"Bad state: Future already completed"StateError。作为目前的解决方法,您可以在每个回调中调用complete 之前检查completer.isCompleted,以防止发生该错误。
猜你喜欢
  • 2023-02-23
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2019-10-02
相关资源
最近更新 更多