Home > Enterprise >  Do not want to complete the Future unless the verifyPhoneNumber method is complete
Do not want to complete the Future unless the verifyPhoneNumber method is complete

Time:10-10

I want to verify a phone number of a user and then only allow that user to signup. But for this when I call verifyPhoneNumber even if I apply await it does not wait till the verification is completed. it executes the next line. So what I want to do is unless the either of verificationCompleted, verificationFailed, codeAutoRetrievalTimeout completes I want to wait and then only executes the code which creates the document for the user in database. Any help will be appreciated!!!

static Future signUp(BuildContext context, String name, String phoneNumber,
      String email, String gender) async {
    await auth.verifyPhoneNumber(
        phoneNumber: phoneNumber,
        verificationCompleted: (credential) async {
          await auth.signInWithCredential(credential);
        },
        verificationFailed: _verificationFailed,
        codeSent: (String verificationId, int resendToken) async{
          await _codeSent(verificationId, resendToken, context);
        },
        codeAutoRetrievalTimeout: (String timeout) {});

    if (auth.currentUser != null) {
      await DB.users.doc(auth.currentUser.uid).set({
        name: name,
        phoneNumber: phoneNumber,
        email: email,
      });
    }
    return;
  }

Thanks!!

CodePudding user response:

You can you .then clause. so in your code you can attach it like below. the value parameter holds any information passed from the code awaited for the then clause.

static Future signUp(BuildContext context, String name, String phoneNumber,
  String email, String gender) async {
await auth.verifyPhoneNumber(
    phoneNumber: phoneNumber,
    verificationCompleted: (credential) async {
      await auth.signInWithCredential(credential);
    },
    verificationFailed: _verificationFailed,
    codeSent: (String verificationId, int resendToken) async{
      await _codeSent(verificationId, resendToken, context);
    },
    codeAutoRetrievalTimeout: (String timeout) {}).then((value){
        //Code you want to execute after the above is completed.
        if (auth.currentUser != null) {
           await DB.users.doc(auth.currentUser.uid).set({
              name: name,
              phoneNumber: phoneNumber,
              email: email,
           });
        }
        return;
      });
}

CodePudding user response:

FirebaseAuth.verifyPhoneNumber starts verification. I expect that its returned Future completes when the verification request has been issued, not when recipient has completed verification.

If you really want a Future that can be awaited, you can use a Completer. One way to use it to transform your set of completion callbacks:

    var verificationCompleter = Completer<PhoneAuthCredential>();
    await auth.verifyPhoneNumber(
        phoneNumber: phoneNumber,
        verificationCompleted: (credential) {
          verificationCompleter.complete(credential);
        },
        verificationFailed: (error) {
          verificationComplete.completeError(error);
        },
        codeSent: (String verificationId, int resendToken) async{
          await _codeSent(verificationId, resendToken, context);
        },
        codeAutoRetrievalTimeout: (String id) {
          verificationComplete.completeError(
            TimeoutException('Verification request timed out'),
          );
        },
    );

    PhoneAuthCredential credential;
    try {
      credential = await verificationComplete.future;
    } on FirebaseAuthException catch (e) {
      _verificationFailed(error);
      return;
    } on TimeoutException {
      // Handle a timeout error however you like.
      // ...
      return;
    }

    await auth.signInWithCredential(credential);
    if (auth.currentUser != null) {
      // ...
    }
  • Related