skip to Main Content

I’m trying to create an auth service and I want to return the verificationId from the custom method. However, calling this method throws the null check exception because it doesn’t wait for the Future to complete before returning.

Future<String> sendPhoneVerification({
    required String phoneNumber,
  }) async {
    String? result;
    await FirebaseAuth.instance.verifyPhoneNumber(
      phoneNumber: '+1$phoneNumber',
      verificationCompleted: (
        PhoneAuthCredential credential,
      ) {
        result = credential.verificationId;
      },
      verificationFailed: (e) {
        if (e.code == 'invalid-phone-number') {
          throw InvalidPhoneNumberAuthException();
        } else if (e.code == 'too-many-requests') {
          throw TooManyRequestsAuthException();
        } else {
          throw GenericAuthException();
        }
      },
      codeSent: (verificationId, resendToken) {
        print('ver_id $verificationId');
        result = verificationId;
      },
      codeAutoRetrievalTimeout: (_) {},
    );
    print('This is the result $result');
    return result!;
  }

Here is the output in the terminal.

flutter: This is the result null
flutter: ver_id <ver_id>

2

Answers


  1. Chosen as BEST ANSWER

    I figured out the solution. I found out the verifyPhoneNumber method returns a future but the implementation doesn't await that async call. I used a [completer][1] to return a future.

    Future<String> sendPhoneVerification({required String phoneNumber}) async {
        Completer<String> result = Completer();
        await FirebaseAuth.instance.verifyPhoneNumber(
          phoneNumber: '+1$phoneNumber',
          verificationCompleted: (
            PhoneAuthCredential credential,
          ) {
            result.complete(credential.verificationId);
          },
          verificationFailed: (e) {
            if (e.code == 'invalid-phone-number') {
              result.completeError(InvalidPhoneNumberAuthException());
            } else if (e.code == 'too-many-requests') {
              result.completeError(TooManyRequestsAuthException());
            } else {
              result.completeError(GenericAuthException());
            }
          },
          codeSent: (verificationId, resendToken) {
            result.complete(verificationId);
          },
          codeAutoRetrievalTimeout: (_) {},
        );
        return result.future;
      }
    

  2. Please add this property timeout: const Duration(seconds: 60), in the verifyPhoneNumber() method

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search