0

I have created signup page in Android that has input field which takes email or phone number , after signup it should receive OTP for the respective input.I have done OTP verification for phone number.My question is my input field accepts either email or phone number. How do I make OTP verification in that case ?

this is the signup activity

package com.example.memorybus

import android.content.ContentValues.TAG
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.example.memorybus.databinding.ActivitySignUpBinding
import com.google.firebase.FirebaseException
import com.google.firebase.FirebaseTooManyRequestsException
import com.google.firebase.auth.*
import java.util.concurrent.TimeUnit

class SignUp : AppCompatActivity() {
    private lateinit var firebaseAuth: FirebaseAuth
    private lateinit var binding: ActivitySignUpBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivitySignUpBinding.inflate(layoutInflater)
        setContentView(binding.root)

        firebaseAuth = FirebaseAuth.getInstance()

        binding.textview.setOnClickListener {
            val intent = Intent(this, Login::class.java)
            startActivity(intent)
        }

        binding.btnSignup.setOnClickListener {
            val name = binding.name.text.toString()
            val email_ph = binding.emailPhone.text.toString()
            val relation = binding.relation.text.toString()
            val password = binding.passwordSignup.text.toString()

            if (email_ph.isNotEmpty())
            {
                val options = PhoneAuthOptions.newBuilder(firebaseAuth)
                    .setPhoneNumber(email_ph)       // Phone number to verify
                    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
                    .setActivity(this)                 // Activity (for callback binding)
                    .setCallbacks(callbacks)          // OnVerificationStateChangedCallbacks
                    .build()
                PhoneAuthProvider.verifyPhoneNumber(options)
            }
            else
            {
                Toast.makeText(this,"Please enter the fields",Toast.LENGTH_SHORT).show()
            }


            }


        }

    private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
        firebaseAuth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    //Log.d(TAG, "signInWithCredential:success")
                    sendToLogin()


                    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
                    }
                    // Update UI
                }
            }
    }

    private fun sendToLogin()
    {
        startActivity(Intent(this,Login::class.java))
    }

    private val callbacks = 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
                Log.w(TAG, "onVerificationFailed", e)
            } else if (e is FirebaseTooManyRequestsException) {
                // The SMS quota for the project has been exceeded
                Log.w(TAG, "onVerificationFailed", e)
            }

            // 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
            val intent = Intent(this@SignUp,OTP::class.java)
            intent.putExtra("OTP", verificationId)
            startActivity(intent)
           /* storedVerificationId = verificationId
            resendToken = token*/
        }
    }


    }
Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
Muralidharan
  • 13
  • 1
  • 5

1 Answers1

1

Firebase Authentication support OTP based authentication for phone numbers only. The email equivalent would be to use email link sign in.

Once user enters their credentials, check if it is a valid email or phone number and call the relevant function.

If you want to use OTPs only then you'll have to build your own solution using Cloud Function similar to this post.

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84