Create cell phone number authentication with Firebase

六月ゝ 毕业季﹏ 提交于 2019-12-30 12:52:28

问题


At present, the options on the Firebase website limit you to prepackaged solutions for authenticating users through Facebook or a person's email, etc. I wish to allow user to login and authenticate using their cell phone number, much like Snapchat allows.

Is there a pre-packaged solution for this? How can this be built out?


回答1:


That is currently not supported. Phone number auth is a tricky feature to implement from a privacy, security and product perspective. That said, if you wish to build it, you will have to implement your own mechanism to send SMS messages with a unique short lived code (corresponding to an allocated uid for a specific phone number) to users using a service like Twilio. You also have to protect against phishing attacks from apps trying to impersonate your app (in the 3 supported platforms) and tricking users to enter the SMS code into their app. Not to mention you have to protect against abuse (malicious users sending SMS messages from your app). Finally when the user redeem the SMS code, you can return a custom token (associated with the allocated uid) which is currently supported by Firebase admin sdk and signInWithCustomToken on the client side completing the sign-in process. This is still an oversimplification of the issue. I suggest you request that feature in the Firebase Google group forum.




回答2:


It is possible. But currently only for iOS/Web. The implementation for Android should be done soon as well. Check firebase docs. https://firebase.google.com/docs/auth/web/phone-auth




回答3:


now phone auth is available in firebase.Here is Code for Phone Auth using Firebase:

EditText phoneNum,Code;// two edit text one for enter phone number other for enter OTP code
Button sent_,Verify;  // sent button to request for verification and verify is for to verify code
private PhoneAuthProvider.ForceResendingToken mResendToken;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private FirebaseAuth mAuth;
private String mVerificationId;

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


    phoneNum =(EditText) findViewById(R.id.fn_num);
    Code =(EditText) findViewById(R.id.code);

    sent_ =(Button)findViewById(R.id.sent_nu);
    Verify =(Button)findViewById(R.id.verify);

    callback_verificvation();                   ///function initialization

    mAuth = FirebaseAuth.getInstance();


    sent_.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String num=phoneNum.getText().toString();
            startPhoneNumberVerification(num);          // call function for receive OTP 6 digit code
        }
    });
    Verify.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String code=Code.getText().toString();
            verifyPhoneNumberWithCode(mVerificationId,code);     //call function for verify code 

        }
    });
}

private void startPhoneNumberVerification(String phoneNumber) {
    // [START start_phone_auth]
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
            phoneNumber,        // Phone number to verify
            60,                 // Timeout duration
            TimeUnit.SECONDS,   // Unit of timeout
            this,               // Activity (for callback binding)
            mCallbacks);        // OnVerificationStateChangedCallbacks
    // [END start_phone_auth]


}

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information

                        FirebaseUser user = task.getResult().getUser();
                        Toast.makeText(getApplicationContext(), "sign in successfull", Toast.LENGTH_SHORT).show();
                        // [START_EXCLUDE]


                    } else {
                        // Sign in failed, display a message and update the UI

                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid

                        }

                    }
                }
            });
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
    // [START verify_with_code]
    PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
    // [END verify_with_code]
    signInWithPhoneAuthCredential(credential);
}


private void callback_verificvation() {

    mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        @Override
        public void onVerificationCompleted(PhoneAuthCredential credential) {
            // 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 verificaiton without
            //     user action.
            // [START_EXCLUDE silent]


            // [START_EXCLUDE silent]

            signInWithPhoneAuthCredential(credential);
        }

        @Override
        public void onVerificationFailed(FirebaseException e) {
            // This callback is invoked in an invalid request for verification is made,
            // for instance if the the phone number format is not valid.
            // [START_EXCLUDE silent]


            if (e instanceof FirebaseAuthInvalidCredentialsException) {
                // Invalid request


                // [END_EXCLUDE]
            } else if (e instanceof FirebaseTooManyRequestsException) {
                // The SMS quota for the project has been exceeded

            }


        }

        @Override
        public void onCodeSent(String verificationId,
                               PhoneAuthProvider.ForceResendingToken token) {
            // 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.


            // Save verification ID and resending token so we can use them later
            mVerificationId = verificationId;
            mResendToken = token;


        }
    };



回答4:


//Deklarasi Variable
private var mAuth: FirebaseAuth? = null
private var mVertificationId: String? = null
private var mToken: PhoneAuthProvider.ForceResendingToken? = null
private var mCallBack: PhoneAuthProvider.OnVerificationStateChangedCallbacks? = null
private var noTelpon: String? = null
private var noTelpon2: String? = null

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_verify)
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    setSupportActionBar(toolbar)
    resend_code.isEnabled = false
    resend_code.setTextColor(Color.parseColor("#FFD2D2D2"))
    progress.visibility = View.VISIBLE
    progmsg.text = "Mohon Tunggu Sebentar...."
    verify.setOnClickListener(this)
    resend_code.setOnClickListener(this)
    resend_code.visibility = View.GONE
    mAuth = FirebaseAuth.getInstance()
    mAuth?.setLanguageCode("id")
    getDataReg()
    sendCode()
}

@SuppressLint("SetTextI18n")
private fun getDataReg(){
    noTelpon = intent.getStringExtra("nomorID")
    noTelpon2 = intent.getStringExtra("nomorID2")
    PhoneNumber.text = noTelpon2
}

private fun sendCode(){
    CallBack()
    // Meminta Firebase Untuk Memverifikasi Nomor Telepon Pengguna
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
        noTelpon!!, //Nomor Telepon Untuk Varifikasi
        45, // Durasi Waktu Habis
        TimeUnit.SECONDS, // Unit Timeout
        this@VerifyActivity, // Activity
        mCallBack as PhoneAuthProvider.OnVerificationStateChangedCallbacks) // OnVerificationStateChangedCallbacks
}

@SuppressLint("SetTextI18n")
private fun resendCode(){
    getDataReg()
    CallBack()
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
        noTelpon!!,
        45,
        TimeUnit.SECONDS,
        this@VerifyActivity,
        mCallBack as PhoneAuthProvider.OnVerificationStateChangedCallbacks,
        mToken) // Digunakan untuk mengirim ulang kembali kode vertifikasi
    progress.visibility = View.VISIBLE
    progmsg.text = "Mengirim ulang kode verifikasi"
    resend_code.visibility = View.GONE
}

// Membuat Instance Yang Berisi Implementasi Dan Fungsi Callback Untuk Menangani Hasil Permintaan
private fun CallBack(){
    mCallBack = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks(){

        @SuppressLint("SetTextI18n")
        override fun onCodeSent(vertificationId: String?, token: PhoneAuthProvider.ForceResendingToken?) {
            // Callback didalam sini akan dipanggil/dieksekusi saat terjadi proses pengiriman kode
            // Dan User Diminta untuk memasukan kode vertifikasi

            // Untuk Menyimpan ID verifikasi dan kirim ulang token
            mVertificationId = vertificationId
            mToken = token
            progress.visibility = View.VISIBLE
            progmsg.text = "Kode verifikasi sedang diproses...."
        }

        @SuppressLint("SetTextI18n")
        override fun onVerificationCompleted(credential: PhoneAuthCredential?) {
            // Callback disini akan dipanggil saat Verifikasi Selseai atau Berhasil
            progmsg.text = ""
            progress.visibility = View.GONE
            signInWithPhoneAuthCredential(credential as PhoneAuthCredential)
        }

        override fun onCodeAutoRetrievalTimeOut(p0: String?) {
            super.onCodeAutoRetrievalTimeOut(p0)
            Toast.makeText(applicationContext, "Verification Time Out!", Toast.LENGTH_SHORT).show()
            progress.visibility = View.GONE
            progmsg.text = ""
            resend_code.visibility = View.VISIBLE
            resend_code.isEnabled = true
        }

        override fun onVerificationFailed(exception: FirebaseException?) {
            // Callback disini akan dipanggil saat permintaan tidak valid atau terdapat kesalahan
            Toast.makeText(applicationContext, "Verifikasi Gagal, Silakan coba lagi", Toast.LENGTH_SHORT).show()
            progress.visibility = View.GONE
            progmsg.text = ""
            resend_code.visibility = View.VISIBLE
            resend_code.isEnabled = true
            Log.e("VerifyActivity.kt", exception?.message)
        }
    }
}

@SuppressLint("SetTextI18n")
private fun Number1(){
    try{
        val code = vertify_num.text.toString()
        if(TextUtils.isEmpty(code)){
            Toast.makeText(applicationContext,"Masukan Kode Verifikasi", Toast.LENGTH_SHORT).show()
        }else{
            // Digunakan Untuk Memvertifikasi Nomor Telepon, Saat Tombol Vertifikasi Ditekan
            val credential: PhoneAuthCredential = PhoneAuthProvider.getCredential(mVertificationId as String, code)
            signInWithPhoneAuthCredential(credential)
            progress.visibility = View.VISIBLE
            progmsg.text = "Sedang diproses, mohon tunggu...."
        }
    }catch (ex: Exception){
        progress.visibility = View.GONE
        progmsg.text = ""
        resend_code.visibility = View.VISIBLE
        resend_code.isEnabled = true
        Toast.makeText(applicationContext,"Kode yang anda masukan salah", Toast.LENGTH_SHORT).show()
    }
}

//Menyimpan data user pada Database SharedPreferences dan Firebase RealtimeDatabase
@SuppressLint("CommitPrefEdits")
private fun profileUser(){
    //Meyimpan data user pada Database didalam Firebase
    val getUser = mAuth!!.currentUser
    val database = FirebaseDatabase.getInstance()
    val reference = database.reference

    //Data probadi dari User dan Provider
    val getUserID = getUser!!.uid
    val getNama = intent.getStringExtra("namaID").toString()
    val getNomor = getUser.phoneNumber
    val setData = DataUser(getNama.toLowerCase(), getNama, getNomor.toString())
    reference.child("Users").child(getUserID).setValue(setData).addOnCompleteListener {
        if(it.isSuccessful){
            SharedPrefManager.getInstance(this).storeUserName(getNama)
            val intent = Intent(this@VerifyActivity, ChooseUser::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
            startActivity(intent)
            finish()
        }else{
            Toast.makeText(applicationContext, "Terjadi Kesalahan", Toast.LENGTH_SHORT).show()
        }
    }
}

//Menangani kejadian jika user berhasil atau gagal saat autentikasi
private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    mAuth?.signInWithCredential(credential)
        ?.addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in Berhasil.
                profileUser()
            } else {
                // Sign in Gagal.
                Log.w("Task Error", "Terjadi Kesalahan Saat Masuk")
                if(task.exception is FirebaseAuthInvalidCredentialsException){
                    // Kode Yang Dimasukan tidal Valid.
                    Toast.makeText(applicationContext, "Kode yang dimasukkan tidak valid", Toast.LENGTH_SHORT).show()
                }
                progress.visibility = View.INVISIBLE
                progmsg.text = ""
            }
        }
}

override fun onClick(v: View?) {
    when(v?.id){
        R.id.verify -> {
            Number1()
            val imm: InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(verify.windowToken, 0)
        }
        R.id.resend_code -> {
            resendCode()
            val imm: InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(resend_code.windowToken, 0)
        }
    }
}

}



来源:https://stackoverflow.com/questions/40967458/create-cell-phone-number-authentication-with-firebase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!