Resend OTP code Firebase phone authentication in Flutter

Viewed 10421

This could be a duplicate BUT any other threads have not provided me a proper answer.

There are answers regarding android native language but none for Flutter(dart).

I have the following Method that works but if i want to resend an OTP to the user phone number How can i do that? Just a simple example code might help.

  Future signInWithPhone(String phone, BuildContext context) async {

    // This triggers if verification passes
    final PhoneVerificationCompleted verificationCompleted = (AuthCredential credential) async {
      Navigator.of(context).pop();

      AuthResult result = await _auth.signInWithCredential(credential);

      FirebaseUser user = result.user;

      if(user != null){
        Navigator.push(context, MaterialPageRoute(
          builder: (context) => HomeScreen(user: user,)
        ));
      }else{
        showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text("Alert Dialog"),
              content: Text('Error'),
            );
          }
        );
      }
    };

    // This triggers if verification fails
    PhoneVerificationFailed verificationFailed = (AuthException exception) {
      toast(exception.message, 'long');
    };

    // This is to send code to the user But i dont know how to resend
    final PhoneCodeSent codeSent = (String verificationId, [int forceResendingToken]) {
        var route = MaterialPageRoute(
          builder: (BuildContext context) => LoginPhoneVerify(verificationId, phone)
        );

        Navigator.of(context).push(route);
    };

    // The main function
    await _auth.verifyPhoneNumber(
      phoneNumber: phone,
      timeout: Duration(seconds: 0),
      verificationCompleted: verificationCompleted,
      verificationFailed: verificationFailed,        
      codeSent: codeSent,
      codeAutoRetrievalTimeout: null
    );


  }

I have found something that is for android in the following thread:

https://stackoverflow.com/a/44688838/10114772

private void resendVerificationCode(String phoneNumber, PhoneAuthProvider.ForceResendingToken token) {
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
            phoneNumber,        // Phone number to verify
            60,                 // Timeout duration
            TimeUnit.SECONDS,   // Unit of timeout
            this,               // Activity (for callback binding)
            mCallbacks,         // OnVerificationStateChangedCallbacks
            token);             // ForceResendingToken from callbacks
}

But thats not for flutter please somebody take a look !

4 Answers

You have to record the value of resendToken from the codesent callback and pass it to the forceresendingtoken. Also, the inbuilt timeout duration is 30 seconds So make sure you tap on resend button after timeout seconds, you may use timerbutton package it's very handy in this case.

Firebase sends 3x same SMS code and then change it to different.

    String _verificationId = "";
    int? _resendToken;

    Future<bool> sendOTP({required String phone}) async {
      await FirebaseAuth.instance.verifyPhoneNumber(
        phoneNumber: phone,
        verificationCompleted: (PhoneAuthCredential credential) {},
        verificationFailed: (FirebaseAuthException e) {},
        codeSent: (String verificationId, int? resendToken) async {
        _verificationId = verificationId;
        _resendToken = resendToken;
        },
        timeout: const Duration(seconds: 25),
        forceResendingToken: _resendToken,
        codeAutoRetrievalTimeout: (String verificationId) {
        verificationId = _verificationId;
      },
     );
   debugPrint("_verificationId: $_verificationId");
   return true;
  }

Record the value of forceResendingToken as resendToken from codeSent callback while sending the otp for first time, then to resend the otp, add one extra parameter forceResendingToken: resendToken in auth.verifyPhoneNumber() function.

So after going through the documentation according to me, recalling

verifyPhoneNumber()

method will resend the OTP code.

I had the same problem, i just disabled the resent button until time out and showed a countdown timer for same duration, after timeout you can enable the resent button and user can resend the code. it worked for me.

Related