sendOTP method

Future<bool> sendOTP({
  1. bool shouldAwaitCodeSend = true,
})

Send OTP to the given _phoneNumber.

Returns true if OTP was sent successfully.

If for any reason, the OTP is not send, _onLoginFailed is called with FirebaseAuthException object to handle the error.

shouldAwaitCodeSend can be used to await the OTP send. The firebase method completes early, and if shouldAwaitCodeSend is false, sendOTP will complete early, and the OTP will be sent in the background. Whereas, if shouldAwaitCodeSend is true, sendOTP will wait for the code send callback to be fired, and sendOTP will complete only after that callback is fired. Not applicable on web.

Implementation

Future<bool> sendOTP({bool shouldAwaitCodeSend = true}) async {
  Completer? codeSendCompleter;

  codeSent = false;
  await Future.delayed(Duration.zero, notifyListeners);

  verificationCompletedCallback(AuthCredential authCredential) async {
    await _loginUser(authCredential: authCredential, autoVerified: true);
  }

  verificationFailedCallback(FirebaseAuthException authException) {
    final stackTrace = authException.stackTrace ?? StackTrace.current;

    if (codeSendCompleter != null && !codeSendCompleter.isCompleted) {
      codeSendCompleter.completeError(authException, stackTrace);
    }
    _onLoginFailed?.call(authException, stackTrace);
  }

  codeSentCallback(
    String verificationId, [
    int? forceResendingToken,
  ]) async {
    _verificationId = verificationId;
    _forceResendingToken = forceResendingToken;
    codeSent = true;
    _onCodeSent?.call();
    if (codeSendCompleter != null && !codeSendCompleter.isCompleted) {
      codeSendCompleter.complete();
    }
    _setTimer();
  }

  codeAutoRetrievalTimeoutCallback(String verificationId) {
    _verificationId = verificationId;
  }

  try {
    if (kIsWeb) {
      _webConfirmationResult = await _auth.signInWithPhoneNumber(
        _phoneNumber!,
        _recaptchaVerifierForWeb,
      );
      codeSent = true;
      _onCodeSent?.call();
      _setTimer();
    } else {
      codeSendCompleter = Completer();

      await _auth.verifyPhoneNumber(
        phoneNumber: _phoneNumber!,
        verificationCompleted: verificationCompletedCallback,
        verificationFailed: verificationFailedCallback,
        codeSent: codeSentCallback,
        codeAutoRetrievalTimeout: codeAutoRetrievalTimeoutCallback,
        timeout: _autoRetrievalTimeOutDuration,
        forceResendingToken: _forceResendingToken,
      );

      if (shouldAwaitCodeSend) await codeSendCompleter.future;
    }

    return true;
  } on FirebaseAuthException catch (e, s) {
    if (codeSendCompleter != null && !codeSendCompleter.isCompleted) {
      codeSendCompleter.completeError(e, s);
    }
    _onLoginFailed?.call(e, s);
    return false;
  } catch (e, s) {
    if (codeSendCompleter != null && !codeSendCompleter.isCompleted) {
      codeSendCompleter.completeError(e, s);
    }
    _onError?.call(e, s);
    return false;
  }
}