Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Phone Authentication Error In Flutter - The sms code has expired. Please re-send the verification code to try again

I implemented Firebase phone authentication (OTP Login) successfully and it was working fine. However, I had to change my keystore alias and generate a new keystore to update the app in Play Store.

Since then, I am facing this issue where it says the otp is wrong every time. Even when I copy-paste the otp from message, it throws the error every time. It is also behaving weird, for some phone numbers, the otp works successfully but for some others, it doesn't. Any little help will be appreciated a lot.

It is important to note that OTP Authentication is working fine in emulators but the error shows up when installed in a real device.

Here's my code snippet below -

String verficationIdRecieved = "";
  int? _resendToken;
  void verifyNumber() {
    auth.verifyPhoneNumber(
      phoneNumber: "+880" + phoneNoController.text,
      verificationCompleted: (PhoneAuthCredential credential) async {
        await auth.signInWithCredential(credential).then((value) async {
          print("verficationCompleted  :  Logged in");
          // Get.offAll(() => OtpVerifyCodeScreen);
        });
      },
      verificationFailed: (FirebaseAuthException exception) {
        LoadingDialog().dismiss();
        print(exception.message);
        getPrefix.Get.snackbar("Error verifyNumber",
            "Please check if your phone number is right. ${exception.message}");
      },
      codeSent: (String verficationId, int? resendToken) async {
        verficationIdRecieved = verficationId;
        _resendToken = resendToken;
        otpCodeVisible = true;
        setState(() {
          timedButtonActtive = true;
        });
        LoadingDialog().dismiss();
      },
      timeout: Duration(seconds: 60),
      forceResendingToken: _resendToken,
      codeAutoRetrievalTimeout: (String verificationId) {
        // ADDED LATER https://stackoverflow.com/questions/61132218/resend-otp-code-firebase-phone-authentication-in-flutter
        // REMOVE IF ERROR
        verficationIdRecieved = verificationId;
      },
    );
  }

  var firebaseToken;
  void verifyCode(BuildContext context) async {
    LoadingDialog().show(context);
    PhoneAuthCredential credential = PhoneAuthProvider.credential(
        verificationId: verficationIdRecieved, smsCode: codeController.text);
    try {
      await auth.signInWithCredential(credential).then((value) {
        // print("\n\n User UID should be   ${value.user!.uid}");
        print("verifyCode  :  Login successfull");
        value.user!.getIdToken().then((value) => {
              firebaseToken = value,
              print("This is the firebase token  ==  $firebaseToken"),
              verifyOtp(
                  mobileNo: phoneNoController.text,
                  otp: codeController.text,
                  ftoken: firebaseToken)
            });
        final snackBar = SnackBar(content: Text("Login Successful"));
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
        // getPrefix.Get.offAll(() => SetUsernameScreen());
      });
    } catch (e) {
      final snackBar = SnackBar(
          content: Text(
              "The sms code has expired or you entered a wrong code. Please re-send the code to try again."));
      ScaffoldMessenger.of(context).showSnackBar(snackBar);
    }
  }
like image 353
Iqbal Rahat Avatar asked Dec 03 '25 04:12

Iqbal Rahat


1 Answers

I think I know your problem.

Android automatically confirms the user as soon as it receives the code before the user clicks the confirmation button.

Saying that you do not have this problem in the emulator is why you receive the code on the real phone.

If you want to manually verify the user, you have two options:

  1. One is to set the timeout to 5 seconds. (So ​​that Android can not automatically verify the user).
  2. The second solution is not to do anything in the verificationCompleted method because now Android is using this method to confirm the user. (My suggestion is to use this way.)

I hope this will solve your problem.

 void verifyNumber() {
auth.verifyPhoneNumber(
  phoneNumber: "+880" + phoneNoController.text,
  verificationCompleted: (PhoneAuthCredential credential) async {
   // await auth.signInWithCredential(credential).then((value) async {  
   //   print("verficationCompleted  :  Logged in");                      //Here
   //   // Get.offAll(() => OtpVerifyCodeScreen); 
   //  });
  },
  verificationFailed: (FirebaseAuthException exception) {
    LoadingDialog().dismiss();
    print(exception.message);
    getPrefix.Get.snackbar("Error verifyNumber",
        "Please check if your phone number is right. ${exception.message}");
  },
  codeSent: (String verficationId, int? resendToken) async {
    verficationIdRecieved = verficationId;
    _resendToken = resendToken;
    otpCodeVisible = true;
    setState(() {
      timedButtonActtive = true;
    });
    LoadingDialog().dismiss();
  },
  timeout: Duration(seconds: 60),
  forceResendingToken: _resendToken,
  codeAutoRetrievalTimeout: (String verificationId) {
    // ADDED LATER https://stackoverflow.com/questions/61132218/resend-otp-code-firebase-phone-authentication-in-flutter
    // REMOVE IF ERROR
    verficationIdRecieved = verificationId;
  },
);
  }
like image 117
Mohammad Taghizadeh Avatar answered Dec 05 '25 21:12

Mohammad Taghizadeh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!