首页 > 解决方案 > 如何在firebase phone-auth (OTP) android中禁用/删除reCaptcha?

问题描述

我启用了 Google Android Device Verification API。我已将 SHA-256 添加到 Firebase 设置并更新了 GSON 文件。并添加后:

Firebase.auth.firebaseAuthSettings.setAppVerificationDisabledForTesting(true) 

我收到 SafetyNet 或 Captcha 未成功的错误(某种错误)。

谁能告诉我如何禁用验证码检查?

这是我的代码

类 OTPNewActivity : AppCompatActivity(), OnKeyboardVisibilityListener, View.OnClickListener { var TAG = "OTPNewActivity"

lateinit var binding: ActivityOtpnewBinding
val action = "android.provider.Telephony.SMS_RECEIVED"

var userEnteredCode = ""
var systemGeneratedCode = ""

var phoneNumer = ""
var phoneDigits = ""

private lateinit var auth: FirebaseAuth

private lateinit var resendToken: PhoneAuthProvider.ForceResendingToken

private var callbacks: PhoneAuthProvider.OnVerificationStateChangedCallbacks =
    object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        override fun onVerificationCompleted(credential: PhoneAuthCredential) {

            Log.d(TAG, "onVerificationCompleted: $credential")
            val code = credential.smsCode

            if (code != null) {
                binding.otpView.setText(code)
                verifyPhoneNumberWithCode(systemGeneratedCode, code!!)
            }
        }

        override fun onVerificationFailed(e: FirebaseException) {

            Log.d(TAG, "onVerificationFailed $e")
            if (e is FirebaseAuthInvalidCredentialsException) {
                Constants.showToast(
                    this@OTPNewActivity,
                    Constants.TOAST_TYPE_FAIL,
                    "Invalid request"
                )
            } else if (e is FirebaseTooManyRequestsException) {
                Constants.showToast(
                    this@OTPNewActivity,
                    Constants.TOAST_TYPE_FAIL,
                    "The SMS quota for the project has been exceeded $e"
                )
            } else {
                Constants.showToast(
                    this@OTPNewActivity,
                    Constants.TOAST_TYPE_FAIL, "Something wents wrong"
                )
            }
        }

        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")
            systemGeneratedCode = verificationId
            resendToken = token

            countdownTimer()
        }
    }


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = DataBindingUtil.setContentView(this, R.layout.activity_otpnew)
    initListeners()
}

private fun initListeners() {
    LocalSharedPreference.getInstance(this).isPhoneNumberVerified = false

// Firebase.auth.firebaseAuthSettings.setAppVerificationDisabledForTesting(true)

    auth = Firebase.auth



    setKeyboardVisibilityListener(this)
    binding.btnNext.setOnClickListener(this)
    binding.tvCount.setOnClickListener(this)
    binding.icBack.setOnClickListener(this)


    val intent = intent
    intent?.let {

        phoneNumer = intent.getStringExtra(Constants.PHONE_NUMBER).toString()
        phoneDigits = intent.getStringExtra(Constants.SAVE_PHONE_DIGITS).toString()

        binding.textView.text =
            "${this.resources.getString(R.string.digit_code)} $phoneNumer"


        val options = PhoneAuthOptions.newBuilder(auth)
            .setPhoneNumber(phoneNumer)
            .setTimeout(15L, TimeUnit.SECONDS)
            .setActivity(this)
            .setCallbacks(callbacks)
             .build()

        PhoneAuthProvider.verifyPhoneNumber(options)


    }

    binding.otpView.setOtpCompletionListener(OnOtpCompletionListener { otp -> // do Stuff
        userEnteredCode = otp
        binding.icNext.visibility = View.VISIBLE
        binding.pbNext.visibility = View.GONE

        verifyPhoneNumberWithCode(systemGeneratedCode, userEnteredCode)


    })

}

private fun verifyPhoneNumberWithCode(verificationId: String?, code: String) {
    try {
        val credential = PhoneAuthProvider.getCredential(verificationId!!, code)

        signInWithPhoneAuthCredential(credential);
    } catch (e: Exception) {
        binding.otpView.setText("")
        Constants.showToast(
            this@OTPNewActivity,
            Constants.TOAST_TYPE_FAIL,
            this@OTPNewActivity.resources.getString(R.string.wrong_Code)
        )
        e.printStackTrace()
    }

}

private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    auth.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")

                LocalSharedPreference.getInstance(this).isPhoneNumberVerified = true

                if (phoneNumer.contains("+52")) {
                    LocalSharedPreference.getInstance(this).setSaveCountry("MX")
                } else if (phoneNumer.contains("+92")) {
                    LocalSharedPreference.getInstance(this).setSaveCountry("PK")
                } else if (phoneNumer.contains("+1")) {
                    LocalSharedPreference.getInstance(this).setSaveCountry("US")
                }

                LocalSharedPreference.getInstance(this).savePhoneNumber(phoneNumer)
                LocalSharedPreference.getInstance(this).setPhoneDigits(phoneDigits)


                val user = task.result?.user
                val intent = Intent(this@OTPNewActivity, ProfileActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
                startActivity(intent)
                finish()

            } else {
                // Sign in failed, display a message and update the UI
                Log.w(TAG, "signInWithCredential:failure", task.exception)
                if (task.exception is FirebaseAuthInvalidCredentialsException) {
                    Constants.showToast(
                        this@OTPNewActivity,
                        Constants.TOAST_TYPE_FAIL,
                        "${task.exception}"
                    )
                }
                // Update UI
            }
        }
}

private fun setKeyboardVisibilityListener(onKeyboardVisibilityListener: OnKeyboardVisibilityListener) {
    val parentView: View = (findViewById<View>(android.R.id.content) as ViewGroup).getChildAt(0)
    parentView.getViewTreeObserver()
        .addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            private var alreadyOpen = false
            private val defaultKeyboardHeightDP = 100
            private val EstimatedKeyboardDP =
                defaultKeyboardHeightDP + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 48 else 0
            private val rect: Rect = Rect()
            override fun onGlobalLayout() {
                val estimatedKeyboardHeight = TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,
                    EstimatedKeyboardDP.toFloat(),
                    parentView.getResources().getDisplayMetrics()
                )
                    .toInt()
                parentView.getWindowVisibleDisplayFrame(rect)
                val heightDiff: Int =
                    parentView.getRootView().getHeight() - (rect.bottom - rect.top)
                val isShown = heightDiff >= estimatedKeyboardHeight
                if (isShown == alreadyOpen) {
                    Log.d("Keyboard state", "Ignoring global layout change...")
                    return
                }
                alreadyOpen = isShown
                onKeyboardVisibilityListener.onVisibilityChanged(isShown)
            }
        })
}

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Checks whether a hardware keyboard is available
    if (newConfig.hardKeyboardHidden === Configuration.HARDKEYBOARDHIDDEN_NO) {
        Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show()
    } else if (newConfig.hardKeyboardHidden === Configuration.HARDKEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show()
    }
}

override fun onVisibilityChanged(visible: Boolean) {
    if (!visible) {
        val imm: InputMethodManager =
            getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(binding.otpView, InputMethodManager.SHOW_IMPLICIT)
    }

}

override fun onResume() {
    super.onResume()
    binding.otpView.requestFocus()


    val imm: InputMethodManager =
        getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(binding.otpView, InputMethodManager.SHOW_IMPLICIT)
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)

    registerReceiver(receiver, IntentFilter(action))


}

private fun countdownTimer() {
    binding.pbNext.visibility = View.VISIBLE
    binding.icNext.visibility = View.GONE

    object : CountDownTimer(15000, 1000) {
        override fun onTick(millisUntilFinished: Long) {
            binding.tvCount.setText("Resend Code in : " + millisUntilFinished / 1000)
        }

        override fun onFinish() {
            binding.tvCount.setText("I didn`t receive a code")
            binding.icNext.visibility = View.VISIBLE
            binding.pbNext.visibility = View.GONE

        }
    }.start()
}

override fun onClick(view: View) {
    when (view.id) {

        R.id.btn_next -> {
            if (binding.otpView.text.toString().length == 6) {

                LocalSharedPreference.getInstance(this@OTPNewActivity).isPhoneNumberVerified =
                    true
                verifyPhoneNumberWithCode(systemGeneratedCode, userEnteredCode)
            }
        }


        R.id.tv_count -> {
            if (binding.tvCount.text.equals(this@OTPNewActivity.resources.getString(R.string.i_dont_received_code)))
                resendVerificationCode(phoneNumer, resendToken)
        }
        R.id.ic_back -> {
            finish()
        }
    }
}


private fun resendVerificationCode(
    phoneNumber: String,
    token: PhoneAuthProvider.ForceResendingToken?
) {
    val optionsBuilder = PhoneAuthOptions.newBuilder(auth)
        .setPhoneNumber(phoneNumber)       // Phone number to verify
        .setTimeout(15L, TimeUnit.SECONDS) // Timeout and unit
        .setActivity(this)                 // Activity (for callback binding)
        .setCallbacks(callbacks)          // OnVerificationStateChangedCallbacks
    if (token != null) {
        optionsBuilder.setForceResendingToken(token) // callback's ForceResendingToken
    }
    PhoneAuthProvider.verifyPhoneNumber(optionsBuilder.build())
}


var receiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        if (intent.action == "android.provider.Telephony.SMS_RECEIVED") {

            val bundle = intent.extras
            var msgs: Array<SmsMessage?>? = null
            var msg_from: String? = ""
            Log.d(TAG, "onReceive called ")
            if (bundle != null) {
                try {
                    val pdus = bundle["pdus"] as Array<Any>?
                    msgs = arrayOfNulls(pdus!!.size)
                    for (i in msgs.indices) {
                        msgs[i] = SmsMessage.createFromPdu(pdus[i] as ByteArray)
                        msg_from = msgs[i]!!.getOriginatingAddress()
                        val msgBody: String = msgs[i]!!.getMessageBody()

                        if (msgBody.contains("is your verification code for running-errands.firebaseapp.com")) {
                            val _1: Char = msgBody[0]
                            val _2: Char = msgBody[1]
                            val _3: Char = msgBody[2]
                            val _4: Char = msgBody[3]
                            val _5: Char = msgBody[4]
                            val _6: Char = msgBody[5]
                            val code: String =
                                _1.toString() + _2.toString() + _3.toString() + _4.toString() + _5.toString() + _6.toString()

// binding.otpView.text = SpannableStringBuilder(code!!)

                            binding.otpView.setText(code)


                            verifyPhoneNumberWithCode(systemGeneratedCode, code!!)

                        }

                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

}


override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(receiver);

}

}

标签: androidfirebasefirebase-authentication

解决方案


推荐阅读