使用firebase进行手机验证,无需身份验证

yrdbyhpb  于 2021-09-29  发布在  Java
关注(0)|答案(0)|浏览(193)

我正在尝试使用下面的代码验证已登录用户提供的手机号码。这是通过firebase电话身份验证完成的,最后一步是在未执行接收凭据的情况下登录firebase。但是没有发送/接收短信。。。应用程序一直崩溃?

initView()
    startVerfiy()

    verifyOTPBtn.setOnClickListener {
        // try to enter the code by yourself to handle the case
        // if user enter another sim card used in another phone ...
        var code = enterOTPNo.text
        Log.e("code is --- ", code.toString())
        if (code != null && !code.isEmpty() && mVerificationId != null && !mVerificationId!!.isEmpty()) {

            showProgressDialog(this, "please wait...", false)

            val credential = PhoneAuthProvider.getCredential(mVerificationId!!, code.toString())
            showMessagesActivity()
//                signInWithPhoneAuthCredential(credential)
        }
    }

    //Resend OTP
    resendOTP.setOnClickListener {
        if (mResendToken != null && !isTimerActive) {
            resendVerificationCode(phoneNumber.toString(), mResendToken)
            showTimer(60000)
            showProgressDialog(this, "Sending a verification code", false)
        } else {
            toast("Sorry, You Can't request new code now, Please wait ...")
        }
    }

    //Reset no option
//        wrong_tv.setOnClickListener {

//            showLoginActivity()
//        }

}

private fun resendVerificationCode(
    phoneNumber: String,
    token: PhoneAuthProvider.ForceResendingToken?
) {
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
        phoneNumber, // Phone number to verify
        60, // Timeout duration
        TimeUnit.SECONDS, // Unit of timeout
        this, // Activity (for callback binding)
        callbacks, // OnVerificationStateChangedCallbacks
        token
    ) // ForceResendingToken from callbacks
}

private fun initView() {
    // init vars from bundle
    phoneNumber = intent.getStringExtra("phoneNumber")

    // init fire base verfiyPhone number callback
    callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        override fun onCodeAutoRetrievalTimeOut(verificationId: String) {
            if (progressDialog != null) {
                dismissProgressDialog(progressDialog)
            }
            notifyUserAndRetry("Time Out :( failed.Retry again!")
        }

        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.e("onVerificationCompleted", "onVerificationCompleted:$credential")
            if (progressDialog != null) {
                dismissProgressDialog(progressDialog)
            }

            val smsMessageSent: String = credential.smsCode.toString()
            Log.e("the message is ----- ", smsMessageSent)
            if (smsMessageSent != null){
                enterOTPNo.setText(smsMessageSent)
            }

            //Saving access setting in Shared Preferences
            val preferences = getSharedPreferences("MessagesAccess", Context.MODE_PRIVATE)
            val editor = preferences.edit()
            editor.putString("noVerified","1")
            editor.apply()
            //Display Messages Activity
            showMessagesActivity()
//                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.e("+++2", "onVerificationFailed", e)

            if (progressDialog != null) {
                dismissProgressDialog(progressDialog)
            }

            if (e is FirebaseAuthInvalidCredentialsException) {
                // Invalid request
                Log.e("Exception:", "FirebaseAuthInvalidCredentialsException", e)
                Log.e("=========:", "FirebaseAuthInvalidCredentialsException " + e.message)

            } else if (e is FirebaseTooManyRequestsException) {
                // The SMS quota for the project has been exceeded
                Log.e("Exception:", "FirebaseTooManyRequestsException", e)
            }

            // Show a message and update the UI
            notifyUserAndRetry("Your Phone Number might be wrong or connection error.Retry again!")

        }

//            override fun onCodeSent(verificationId: String?, token: PhoneAuthProvider.ForceResendingToken) {
//                //for low level version which doesn't do auto verification save the verification code and the token
//
//                dismissProgressDialog(progressDialog)
//                timeRemaining.visibility = View.GONE
//                // Save verification ID and resending token so we can use them later
//                Log.e("onCodeSent===", "onCodeSent:$verificationId")
//
//                mVerificationId = verificationId
//                mResendToken = token
//
//            }
    }
}

private fun startVerfiy() {

    Log.e("User Phone Number ===  ", phoneNumber!!)

    if (phoneNumber != null && !phoneNumber!!.isEmpty()) {
        startPhoneNumberVerification(phoneNumber!!)
        showTimer(60000)
        showProgressDialog(this, "Sending a verification code", false)
    } else {
        toast("Please enter a valid number to continue!")
    }
}

//    private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
//        val mAuth = FirebaseAuth.getInstance()
//        mAuth.signInWithCredential(credential)
//            .addOnCompleteListener(this) { task ->
//                if (task.isSuccessful) {
//
//                    if (progressDialog != null) {
//                        dismissProgressDialog(progressDialog)
//                    }
//
//                    val user = task.result.user
//                    Log.e("Sign in with phone auth", "Success $user")
//                    showMessagesActivity()
//                } else {
//
//                    if (progressDialog != null) {
//                        dismissProgressDialog(progressDialog)
//                    }
//
//                    notifyUserAndRetry("Your Phone Number Verification is failed.Retry again!")
//                }
//            }
//    }

// This method will send a code to a given phone number as an SMS
private fun startPhoneNumberVerification(phoneNumber: String) {
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
        phoneNumber,      // Phone number to verify
        60,               // Timeout duration
        TimeUnit.SECONDS, // Unit of timeout
        this,            // Activity (for callback binding)
        callbacks
    ) // OnVerificationStateChangedCallbacks
}

private fun notifyUserAndRetry(message: String) {
    val alertDialogBuilder = AlertDialog.Builder(this)
    alertDialogBuilder.setMessage(message)
    alertDialogBuilder.setPositiveButton("Ok",
        DialogInterface.OnClickListener { arg0, arg1 -> showLoginActivity() })

    alertDialogBuilder.setNegativeButton("Cancel",
        DialogInterface.OnClickListener { dialog, which -> showLoginActivity() })

    val alertDialog = alertDialogBuilder.create()
    alertDialog.show()
}

// helpers methods :)
private fun toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

private fun showTimer(milliesInFuture: Long) {
    isTimerActive = true
    mCounterDown = object : CountDownTimer(milliesInFuture, 1000) {

        override fun onTick(millisUntilFinished: Long) {
            timeLeft = millisUntilFinished
            timeRemaining.visibility = View.VISIBLE
            timeRemaining.text = "seconds remaining: " + millisUntilFinished / 1000

            //here you can have your logic to set text to edittext
        }

        override fun onFinish() {
            timeRemaining.visibility = View.GONE
            isTimerActive = false
        }

    }.start()
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putLong("timeLeft", timeLeft)
    outState.putString("phoneNumber", phoneNumber)
}

private fun showProgressDialog(
    mActivity: Context,
    message: String,
    isCancelable: Boolean
): ProgressDialog {
    progressDialog = ProgressDialog(mActivity)
    progressDialog!!.show()
    progressDialog!!.setCancelable(isCancelable)
    progressDialog!!.setCanceledOnTouchOutside(false)
    progressDialog!!.setMessage(message)
    return progressDialog as ProgressDialog
}

private fun dismissProgressDialog(progressDialog: ProgressDialog?) {
    if (progressDialog != null && progressDialog.isShowing) {
        progressDialog.dismiss()
    }
}

private fun showLoginActivity() {
    startActivity(
        Intent(this, LoginPhoneScreen::class.java)
            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
    )
}

private fun showMessagesActivity() {

    //first save phone number to data base and then call TODO worker to sync phone numbers for contacts

    firebaseUser = FirebaseAuth.getInstance().currentUser
    refUsers = FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUser!!.uid)
    phoneRefUsers = FirebaseDatabase.getInstance().reference.child("PhoneDirectory").child(phoneNumber!!)

    //to save message on Firebase - Users Node
    val usersHashMap = HashMap<String, Any?>()
    usersHashMap["verPhone"] = phoneNumber

    val phoneDirectoryHashMap = HashMap<String, Any?>()
    phoneDirectoryHashMap["userId"] = firebaseUser!!.uid

    //to save message on Firebase - Users Phone Directory Node
    phoneRefUsers!!.updateChildren(phoneDirectoryHashMap).addOnCompleteListener {
        refUsers!!.updateChildren(usersHashMap)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val intent = Intent(this, Messages::class.java)
                    startActivity(intent)
                    finish()
                }
            }
    }

}

override fun onBackPressed() {
    finish()
}

override fun onDestroy() {
    super.onDestroy()
    if (mCounterDown != null) {
        mCounterDown!!.cancel()
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题