avishak chakroborty
avishak chakroborty

Reputation: 312

Firebase Authentication using Sms verification is not working properly

I used Firebase Authentication using Phone number in My android application.

The authentication works fine when you enter the number for the first time and it can automatically detect the OTP if the app is opened in the same android device the provided phone number is given.

But when I enter the mobile number again it does not send the verification sms containing OTP.

here is the class where the phone number is provided.

public class LoginActivity extends AppCompatActivity {

    private EditText LoginPhone;
    private Button LoginConfirmButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        LoginPhone = (EditText) findViewById(R.id.PhoneNumberLogin);
        LoginConfirmButton = (Button) findViewById(R.id.Loginbutton);
        Button registerbutton=(Button)findViewById(R.id.RegisterButton);

        LoginConfirmButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String number=LoginPhone.getText().toString();
                if(number.isEmpty() || number.length()<11)
                {
                    LoginPhone.setError("Valied Number Required");
                    LoginPhone.requestFocus();
                }

                String PhoneNumber="+88"+number;
                Intent firstintent=new Intent(LoginActivity.this,CodeConfirm.class);
                firstintent.putExtra("PhoneNumber",PhoneNumber);
                startActivity(firstintent);
            }
        });

        registerbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(LoginActivity.this,User_Registration.class));
            }
        });
    }
}

And Here is the Class where The user can put the OTP manually.

public class CodeConfirm extends AppCompatActivity {

    EditText Otpverify;
    int s;
    private String VerificationCode;
    Button confirmbutton;
    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_code_confirm);

        Otpverify = (EditText) findViewById(R.id.ConfirmCode);
        mAuth= FirebaseAuth.getInstance();
        String PhoneNumber = getIntent().getStringExtra("PhoneNumber");

        SendVerificationCode(PhoneNumber);

        confirmbutton=(Button)findViewById(R.id.ConfirmButton);

        confirmbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String code=Otpverify.getText().toString().trim();

                if(code.isEmpty() || code.length()<6)
                {
                    Otpverify.setError("Enter the OTP properly");
                    Otpverify.requestFocus();
                    return;
                }
                Verifycode(code);
            }
        });
    }

    private void Verifycode(String code) {
        PhoneAuthCredential credential=PhoneAuthProvider.getCredential(VerificationCode,code);
        Signin(credential);

    }

    private void Signin(PhoneAuthCredential credential) {

        mAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {

                if(task.isSuccessful())
                {
                    Intent WorkingSwitch=new Intent(CodeConfirm.this,Current_Location.class);
                    WorkingSwitch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(WorkingSwitch);
                }
            }
        });
    }

    private void SendVerificationCode(String Number) {

        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                Number,
                60,
                TimeUnit.SECONDS,
                TaskExecutors.MAIN_THREAD,
                mCallBack
        );
    }

    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallBack = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        @Override
        public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {

            String code=phoneAuthCredential.getSmsCode();
            if(code!=null)
            {
                Verifycode(code);
            }
        }

        @Override
        public void onVerificationFailed(FirebaseException e) {

            Toast.makeText(CodeConfirm.this,e.getMessage(),Toast.LENGTH_LONG).show();

        }

        @Override
        public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
            super.onCodeSent(s, forceResendingToken);
            VerificationCode=s;
        }
    };
}

I want to send the OTP to the phone number every time the number is provided even when if same number is provided multiple times.

Upvotes: 3

Views: 6427

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599341

The verifyPhoneNumber method does not send an OTP if the number has been recently verified, if a verification is already in progress for the number, or if too many verification request were sent to the number recently.

Also note this from the documentation:

To prevent abuse, Firebase enforces a limit on the number of SMS messages that can be sent to a single phone number within a period of time. If you exceed this limit, phone number verification requests might be throttled. If you encounter this issue during development, use a different phone number for testing, or try the request again later.

If you want to force it to send a new OTP, use the verifyPhoneNumber overload that takes a forceResendingToken parameter which you get from the previous onCodeSent.

If you want to send to the same number for testing, whitelisting the number is a better option.

Upvotes: 4

Related Questions