inside firebase console project go to Authentication section after setting up Project in both android studio and firebase console connection with project properly.
than go to sign-in method section and click on get Started if no other provider are created or click on Add new provider if other method are created that Select Phone From Native Provider section and finish set up.
Step 1
above / before onCreate() method (Class Scope)
private val TAG: String = "+=+=+="
private lateinit var auth: FirebaseAuth
private var storedVerificationId: String? = ""
private lateinit var resendToken: PhoneAuthProvider.ForceResendingToken
Step 2
add all this objects and method inside activity / fragment where we will be submitting otp
fun resendOtp() {
binding.resendOtp.isEnabled = false
val countdown = object : CountDownTimer(60000, 1000) {
override fun onTick(millisUntilFinished: Long) {
binding.resendOtp.text = "resend in: ${millisUntilFinished / 1000}s"
}
override fun onFinish() {
binding.resendOtp.text = "resend otp"
binding.resendOtp.isEnabled = true
}
}
countdown.start()
}
private var callbacks: PhoneAuthProvider.OnVerificationStateChangedCallbacks =
object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(credential: PhoneAuthCredential) {
// This callback will be invoked in two situations:
// 1 - Instant verification. In some cases the phone number can be instantly
// verified without needing to send or enter a verification code.
// 2 - Auto-retrieval. On some devices Google Play services can automatically
// detect the incoming verification SMS and perform verification without
// user action.
Log.d(TAG, "onVerificationCompleted:$credential")
signInWithPhoneAuthCredential(credential)
}
override fun onVerificationFailed(e: FirebaseException) {
// This callback is invoked in an invalid request for verification is made,
// for instance if the the phone number format is not valid.
Log.w(TAG, "onVerificationFailed", e)
if (e is FirebaseAuthInvalidCredentialsException) {
// Invalid request
} else if (e is FirebaseTooManyRequestsException) {
// The SMS quota for the project has been exceeded
} else if (e is FirebaseAuthMissingActivityForRecaptchaException) {
// reCAPTCHA verification attempted with null Activity
}
// Show a message and update the UI
}
override fun onCodeSent(
verificationId: String,
token: PhoneAuthProvider.ForceResendingToken,
) {
// The SMS verification code has been sent to the provided phone number, we
// now need to ask the user to enter the code and then construct a credential
// by combining the code with a verification ID.
Log.d(TAG, "onCodeSent:$verificationId")
// Save verification ID and resending token so we can use them later
// do something when code is recevied
storedVerificationId = verificationId
resendToken = token
}
}
private fun startPhoneNumberVerification(phoneNumber: String) {
// [START start_phone_auth]
val options = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(phoneNumber) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this@PhoneSignIn) // Activity (for callback binding)
.setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
.build()
PhoneAuthProvider.verifyPhoneNumber(options)
// [END start_phone_auth]
}
private fun verifyPhoneNumberWithCode(verificationId: String?, code: String) {
// [START verify_with_code]
val credential = PhoneAuthProvider.getCredential(verificationId!!, code)
signInWithPhoneAuthCredential(credential)
// [END verify_with_code]
}
private fun resendVerificationCode(
phoneNumber: String,
token: PhoneAuthProvider.ForceResendingToken?,
) {
val optionsBuilder = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(phoneNumber) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this@PhoneSignIn) // (optional) Activity for callback binding
// If no activity is passed, reCAPTCHA verification can not be used.
.setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
if (token != null) {
optionsBuilder.setForceResendingToken(token) // callback's ForceResendingToken
}
PhoneAuthProvider.verifyPhoneNumber(optionsBuilder.build())
}
private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
auth.signInWithCredential(credential)
.addOnCompleteListener(this@PhoneSignIn) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success")
Toast.makeText(this@PhoneSignIn, "Login Success", Toast.LENGTH_SHORT).show()
val user = task.result?.user
} else {
// Sign in failed, display a message and update the UI
Log.w(TAG, "signInWithCredential:failure", task.exception)
if (task.exception is FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
Toast.makeText(
this@PhoneSignIn,
task.exception?.localizedMessage,
Toast.LENGTH_SHORT
).show()
}
Toast.makeText(
this@PhoneSignIn,
task.exception?.localizedMessage,
Toast.LENGTH_SHORT
).show()
// Update UI
}
}
}
step 3
inside onCreate() method of activity.
auth = Firebase.auth
binding.generateOtp.setOnClickListener {
if (binding.generateOtp.text == "Generate OTP") {
val phoneNumber = "+91${binding.edtPhone.text}"
startPhoneNumberVerification(phoneNumber)
resendOtp()
} else {
val code = binding.submitOtp.text.toString()
verifyPhoneNumberWithCode(storedVerificationId, code)
}
}
binding.resendOtp.setOnClickListener {
val phoneNumber = "+91${binding.edtPhone.text}"
resendVerificationCode(phoneNumber, resendToken)
resendOtp()
}
step 4
create UI and per need and check documentation for further query.