Firebase手机号认证异常:OTP无法发送,报1005错误
Firebase Phone Auth 1005错误解决指南
问题描述
E/FirebaseAuth : [SmsRetriverHelper] Sms verification code failed: unknown status code : 1005 null
无法向手机号发送OTP,点击send Otp按钮后会打开浏览器要求验证验证码,完成操作后出现上述错误。
相关代码
login.kt
package com.example.egc5 import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.View import android.widget.Button import android.widget.EditText import android.widget.ProgressBar import android.widget.Toast import com.google.firebase.FirebaseException import com.google.firebase.FirebaseTooManyRequestsException import com.google.firebase.auth.* import java.util.concurrent.TimeUnit class log_in : AppCompatActivity() { private lateinit var sendOTPBtn : Button private lateinit var phoneNumberET : EditText private lateinit var auth : FirebaseAuth private lateinit var number : String private lateinit var mProgressBar : ProgressBar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_log_in) init() sendOTPBtn.setOnClickListener { number = phoneNumberET.text.trim().toString() if (number.isNotEmpty()){ if (number.length == 10){ number = "+91$number" mProgressBar.visibility = View.VISIBLE val options = PhoneAuthOptions.newBuilder(auth) .setPhoneNumber(number) // 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 correct Number" , Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(this , "Please Enter Number" , Toast.LENGTH_SHORT).show() } } if (supportActionBar != null) { supportActionBar!!.hide() } } private fun init(){ mProgressBar = findViewById(R.id.phoneProgressBar) mProgressBar.visibility = View.INVISIBLE sendOTPBtn = findViewById(R.id.sendOTPBtn) phoneNumberET = findViewById(R.id.phoneEditTextNumber) auth = FirebaseAuth.getInstance() } 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 Toast.makeText(this , "Authenticate Successfully" , Toast.LENGTH_SHORT).show() sendToMain() } else { // Sign in failed, display a message and update the UI Log.d("TAG", "signInWithPhoneAuthCredential: ${task.exception.toString()}") if (task.exception is FirebaseAuthInvalidCredentialsException) { Toast.makeText(this , "TRY AGAIN" , Toast.LENGTH_SHORT).show() // The verification code entered was invalid } // Update UI } mProgressBar.visibility = View.INVISIBLE } } private fun sendToMain(){ startActivity(Intent(this , MainActivity2::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. 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. if (e is FirebaseAuthInvalidCredentialsException) { // Invalid request Log.d("TAG", "onVerificationFailed: ${e.toString()}") } else if (e is FirebaseTooManyRequestsException) { // The SMS quota for the project has been exceeded Log.d("TAG", "onVerificationFailed: ${e.toString()}") } mProgressBar.visibility = View.INVISIBLE } 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. // Save verification ID and resending token so we can use them later val intent = Intent(this@log_in , otp::class.java) intent.putExtra("OTP" , verificationId) intent.putExtra("resendToken" , token) intent.putExtra("phoneNumber" , number) startActivity(intent) mProgressBar.visibility = View.INVISIBLE } } override fun onStart() { super.onStart() if (auth.currentUser != null){ startActivity(Intent(this , MainActivity2::class.java)) } } }
otp.kt
package com.example.egc5 import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View import android.widget.* import androidx.appcompat.app.AppCompatActivity import com.google.firebase.FirebaseException import com.google.firebase.FirebaseTooManyRequestsException import com.google.firebase.auth.* import java.util.concurrent.TimeUnit class otp : AppCompatActivity() { private lateinit var auth: FirebaseAuth private lateinit var verifyBtn: Button private lateinit var resendTV: TextView private lateinit var inputOTP1: EditText private lateinit var inputOTP2: EditText private lateinit var inputOTP3: EditText private lateinit var inputOTP4: EditText private lateinit var inputOTP5: EditText private lateinit var inputOTP6: EditText private lateinit var progressBar: ProgressBar private lateinit var OTP: String private lateinit var resendToken: PhoneAuthProvider.ForceResendingToken private lateinit var phoneNumber: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_otp) OTP = intent.getStringExtra("OTP").toString() resendToken = intent.getParcelableExtra("resendToken")!! phoneNumber = intent.getStringExtra("phoneNumber")!! init() progressBar.visibility = View.INVISIBLE addTextChangeListener() resendOTPTvVisibility() resendTV.setOnClickListener { resendVerificationCode() resendOTPTvVisibility() } if (supportActionBar != null) { supportActionBar!!.hide() } verifyBtn.setOnClickListener { //collect otp from all the edit texts val typedOTP = (inputOTP1.text.toString() + inputOTP2.text.toString() + inputOTP3.text.toString() + inputOTP4.text.toString() + inputOTP5.text.toString() + inputOTP6.text.toString()) if (typedOTP.isNotEmpty()) { if (typedOTP.length == 6) { val credential: PhoneAuthCredential = PhoneAuthProvider.getCredential( OTP, typedOTP ) progressBar.visibility = View.VISIBLE signInWithPhoneAuthCredential(credential) } else { Toast.makeText(this, "Please Enter Correct OTP", Toast.LENGTH_SHORT).show() } } else { Toast.makeText(this, "Please Enter OTP", Toast.LENGTH_SHORT).show() } } } private fun resendOTPTvVisibility() { inputOTP1.setText("") inputOTP2.setText("") inputOTP3.setText("") inputOTP4.setText("") inputOTP5.setText("") inputOTP6.setText("") resendTV.visibility = View.INVISIBLE resendTV.isEnabled = false Handler(Looper.myLooper()!!).postDelayed({ resendTV.visibility = View.VISIBLE resendTV.isEnabled = true }, 60000) } private fun resendVerificationCode() { val options = PhoneAuthOptions.newBuilder(auth) .setPhoneNumber(phoneNumber) // Phone number to verify .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit .setActivity(this) // Activity (for callback binding) .setCallbacks(callbacks) .setForceResendingToken(resendToken)// OnVerificationStateChangedCallbacks .build() PhoneAuthProvider.verifyPhoneNumber(options) } 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. 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. if (e is FirebaseAuthInvalidCredentialsException) { // Invalid request Log.d("TAG", "onVerificationFailed: ${e.toString()}") } else if (e is FirebaseTooManyRequestsException) { // The SMS quota for the project has been exceeded Log.d("TAG", "onVerificationFailed: ${e.toString()}") } progressBar.visibility = View.INVISIBLE } 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. // Save verification ID and resending token so we can use them later OTP = verificationId resendToken = token } } 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 Toast.makeText(this, "Authenticate Successfully", Toast.LENGTH_SHORT).show() sendToMain() } else { // Sign in failed, display a message and update the UI Log.d("TAG", "signInWithPhoneAuthCredential: ${task.exception.toString()}") if (task.exception is FirebaseAuthInvalidCredentialsException) { // The verification code entered was invalid Toast.makeText(this, "Try Again", Toast.LENGTH_SHORT).show() } // Update UI } progressBar.visibility = View.INVISIBLE } } private fun sendToMain() { startActivity(Intent(this, MainActivity::class.java)) } private fun addTextChangeListener() { inputOTP1.addTextChangedListener(EditTextWatcher(inputOTP1)) inputOTP2.addTextChangedListener(EditTextWatcher(inputOTP2)) inputOTP3.addTextChangedListener(EditTextWatcher(inputOTP3)) inputOTP4.addTextChangedListener(EditTextWatcher(inputOTP4)) inputOTP5.addTextChangedListener(EditTextWatcher(inputOTP5)) inputOTP6.addTextChangedListener(EditTextWatcher(inputOTP6)) } private fun init() { auth = FirebaseAuth.getInstance() progressBar = findViewById(R.id.otpProgressBar) verifyBtn = findViewById(R.id.verifyOTPBtn) resendTV = findViewById(R.id.resendTextView) inputOTP1 = findViewById(R.id.otpEditText1) inputOTP2 = findViewById(R.id.otpEditText2) inputOTP3 = findViewById(R.id.otpEditText3) inputOTP4 = findViewById(R.id.otpEditText4) inputOTP5 = findViewById(R.id.otpEditText5) inputOTP6 = findViewById(R.id.otpEditText6) } inner class EditTextWatcher(private val view: View) : TextWatcher { override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { } override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { } override fun afterTextChanged(p0: Editable?) { val text = p0.toString() when (view.id) { R.id.otpEditText1 -> if (text.length == 1) inputOTP2.requestFocus() R.id.otpEditText2 -> if (text.length == 1) inputOTP3.requestFocus() else if (text.isEmpty()) inputOTP1.requestFocus() R.id.otpEditText3 -> if (text.length == 1) inputOTP4.requestFocus() else if (text.isEmpty()) inputOTP2.requestFocus() R.id.otpEditText4 -> if (text.length == 1) inputOTP5.requestFocus() else if (text.isEmpty()) inputOTP3.requestFocus() R.id.otpEditText5 -> if (text.length == 1) inputOTP6.requestFocus() else if (text.isEmpty()) inputOTP4.requestFocus() R.id.otpEditText6 -> if (text.isEmpty()) inputOTP5.requestFocus() } } } }
解决方案
1. 核对应用签名SHA-1
Firebase Phone Auth要求应用签名与控制台配置完全匹配:
- 运行
./gradlew signingReport(Windows用gradlew.bat signingReport)获取debug/release版本的SHA-1值。 - 登录Firebase控制台,进入项目设置,在"你的应用"板块添加对应SHA-1,保存后等待配置生效(通常需要数分钟)。
2. 启用Android设备验证
在Firebase控制台的Authentication > 登录方式中,开启"电话"登录,并确保勾选"Android设备验证"选项。该选项可跳过浏览器验证,直接通过设备发送OTP,避免1005错误。
3. 修复代码中的进度条状态错误
原代码中onVerificationFailed和signInWithPhoneAuthCredential回调里错误地将进度条设为VISIBLE,导致验证失败后进度条一直显示,已在上述代码中修正为INVISIBLE,请同步修改你的代码。
4. 检查PhoneAuth配置与设备环境
- 确保
PhoneAuthOptions的setActivity参数绑定当前Activity,避免上下文错误。 - 清除应用缓存和Google Play服务缓存,重启设备后重新测试。
- 确认手机号格式正确(已添加+91前缀,用户输入纯数字)。
内容的提问来源于stack exchange,提问作者Yt learn India
相关产品推荐
相关产品推荐

