3

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);
    }
  }
Iqbal Rahat
  • 87
  • 1
  • 8

1 Answers1

2

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;
  },
);
  }