Kotlin Firebase骑手端手机号验证后应用崩溃问题求助
骑手端Firebase手机号验证后崩溃及验证提示问题排查与修复
问题描述
我正在开发基于Kotlin与Firebase的骑手端应用,期望完成手机号验证后跳转至HomeActivity,但应用出现崩溃,无法定位原因。已在Firebase中关联司机端与骑手端两个应用,司机端运行正常,骑手端却提示“手机号需要验证”,且已在Firebase中手动添加相关手机号。
修复后完整代码
package com.example.driveeaserider import android.app.Activity import android.app.AlertDialog import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.text.TextUtils import android.view.LayoutInflater import android.view.View import android.widget.Button import android.widget.ProgressBar import android.widget.Toast import com.example.driveeaserider.Common.Common import com.example.driveeaserider.Model.RiderModel import com.firebase.ui.auth.AuthMethodPickerLayout import com.firebase.ui.auth.AuthUI import com.firebase.ui.auth.IdpResponse import com.google.android.material.textfield.TextInputEditText import com.google.firebase.auth.FirebaseAuth import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DatabaseError import com.google.firebase.database.DatabaseReference import com.google.firebase.database.FirebaseDatabase import com.google.firebase.database.ValueEventListener import io.reactivex.Completable import io.reactivex.android.schedulers.AndroidSchedulers import java.util.Arrays import java.util.concurrent.TimeUnit class SplashScreenActivity : AppCompatActivity() { companion object { private val LOGIN_REQUEST_CODE = 7171 } lateinit var provider: List<AuthUI.IdpConfig> lateinit var firebaseAuth: FirebaseAuth lateinit var listener: FirebaseAuth.AuthStateListener private lateinit var database: FirebaseDatabase private lateinit var riderInfoRef: DatabaseReference private lateinit var progressBar: ProgressBar override fun onStart() { super.onStart() delaySplashScreen() } private fun delaySplashScreen() { Completable.timer(3,TimeUnit.SECONDS,AndroidSchedulers.mainThread()) .subscribe({ val currentUser = firebaseAuth.currentUser if(currentUser != null) { checkUserFromFirebase() } else { firebaseAuth.addAuthStateListener(listener) } }) } override fun onStop() { if (firebaseAuth != null && listener != null) firebaseAuth.removeAuthStateListener(listener) super.onStop() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_splash_screen) progressBar = findViewById(R.id.progress_bar) init() } private fun init() { database = FirebaseDatabase.getInstance() riderInfoRef = database.getReference(Common.RIDER_INFO_REFERENCE) provider = Arrays.asList( AuthUI.IdpConfig.PhoneBuilder().build(), AuthUI.IdpConfig.GoogleBuilder().build() ) firebaseAuth = FirebaseAuth.getInstance() listener = FirebaseAuth.AuthStateListener { myFirebaseAuth -> val user = myFirebaseAuth.currentUser if(user != null) { checkUserFromFirebase() } else { showLoginLayout() } } } private fun showLoginLayout() { val authMethodPickerLayout = AuthMethodPickerLayout.Builder(R.layout.activity_sign_in) .setPhoneButtonId(R.id.btn_phone_sign_in) .setGoogleButtonId(R.id.btn_google_sign_in) .build() startActivityForResult(AuthUI.getInstance() .createSignInIntentBuilder() .setAuthMethodPickerLayout(authMethodPickerLayout) .setTheme(R.style.SignInTheme) .setAvailableProviders(provider) .setIsSmartLockEnabled(false) .build(), LOGIN_REQUEST_CODE ) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if(requestCode == LOGIN_REQUEST_CODE) { val response = IdpResponse.fromResultIntent(data) if(resultCode == Activity.RESULT_OK) { val user = FirebaseAuth.getInstance().currentUser user?.let { checkUserFromFirebase() } } else { val errorMsg = response?.error?.message ?: "登录失败" Toast.makeText(this@SplashScreenActivity, errorMsg, Toast.LENGTH_LONG).show() } } } private fun checkUserFromFirebase() { riderInfoRef.child(FirebaseAuth.getInstance().currentUser!!.uid) .addListenerForSingleValueEvent(object:ValueEventListener{ override fun onDataChange(p0: DataSnapshot) { if(p0.exists()) { val model = p0.getValue(RiderModel::class.java) goToHomeActivity(model) } else { showRegisterLayout() } } override fun onCancelled(p0: DatabaseError) { Toast.makeText(this@SplashScreenActivity,p0.message,Toast.LENGTH_LONG).show() } }) } private fun showRegisterLayout() { val builder = AlertDialog.Builder(this,R.style.DialogTheme) val itemView = LayoutInflater.from(this).inflate(R.layout.layout_register,null) val edt_first_name = itemView.findViewById<View>(R.id.edt_first_name) as TextInputEditText val edt_last_name = itemView.findViewById<View>(R.id.edt_last_name) as TextInputEditText val edt_phone_number = itemView.findViewById<View>(R.id.edt_phone_number) as TextInputEditText val btn_continue = itemView.findViewById<View>(R.id.btn_register) as Button // 修复手机号预填逻辑 FirebaseAuth.getInstance().currentUser?.phoneNumber?.let { phone -> if(TextUtils.isDigitsOnly(phone)) { edt_phone_number.setText(phone) } } builder.setView(itemView) val dialog = builder.create() dialog.show() // 修复输入验证逻辑 btn_continue.setOnClickListener{ val firstName = edt_first_name.text.toString().trim() val lastName = edt_last_name.text.toString().trim() val phoneNumber = edt_phone_number.text.toString().trim() when { TextUtils.isEmpty(firstName) -> { Toast.makeText(this@SplashScreenActivity,"请输入名字",Toast.LENGTH_SHORT).show() return@setOnClickListener } TextUtils.isDigitsOnly(firstName) -> { Toast.makeText(this@SplashScreenActivity,"名字不能全是数字",Toast.LENGTH_SHORT).show() return@setOnClickListener } TextUtils.isEmpty(lastName) -> { Toast.makeText(this@SplashScreenActivity,"请输入姓氏",Toast.LENGTH_SHORT).show() return@setOnClickListener } TextUtils.isDigitsOnly(lastName) -> { Toast.makeText(this@SplashScreenActivity,"姓氏不能全是数字",Toast.LENGTH_SHORT).show() return@setOnClickListener } TextUtils.isEmpty(phoneNumber) -> { Toast.makeText(this@SplashScreenActivity,"请输入手机号",Toast.LENGTH_SHORT).show() return@setOnClickListener } !TextUtils.isDigitsOnly(phoneNumber) -> { Toast.makeText(this@SplashScreenActivity,"手机号必须全是数字",Toast.LENGTH_SHORT).show() return@setOnClickListener } else -> { val model = RiderModel() model.firstName = firstName model.lastName = lastName model.phoneNumber = phoneNumber progressBar.visibility = View.VISIBLE riderInfoRef.child(FirebaseAuth.getInstance().currentUser!!.uid) .setValue(model) .addOnFailureListener{ e -> Toast.makeText(this@SplashScreenActivity,"${e.message}",Toast.LENGTH_SHORT).show() dialog.dismiss() progressBar.visibility = View.GONE } .addOnSuccessListener { Toast.makeText(this@SplashScreenActivity,"注册成功!",Toast.LENGTH_SHORT).show() dialog.dismiss() goToHomeActivity(model) progressBar.visibility = View.GONE } } } } } private fun goToHomeActivity(model: RiderModel?) { Common.currentRider = model startActivity(Intent(this,HomeActivity::class.java)) finish() } }
核心问题与修复说明
1. 空指针异常修复
onActivityResult错误处理:原代码直接强制解包response!!.error!!,空值时触发崩溃,改为空安全判断并提供默认提示;登录成功后手动调用checkUserFromFirebase,避免AuthStateListener未触发导致流程停滞。- ProgressBar绑定:原代码在弹窗中临时获取ProgressBar,可能因布局层级问题返回null,改为在Activity初始化时绑定成员变量,确保非空。
2. 输入验证逻辑修复
- 修正姓名验证逻辑:优先检查是否为空,再判断是否全为数字;
- 修正手机号验证逻辑:检查是否为空且是否为纯数字;
- 修复手机号预填判断条件,确保只有合法手机号才会自动填充。
3. “手机号需要验证”提示解决
- 确认骑手端
google-services.json是从Firebase控制台对应应用下载的,与司机端配置区分开; - 检查Firebase控制台中骑手应用的登录方法,确保手机号登录已启用,并添加正确的SHA-1证书指纹(含调试、发布版本);
- 手动添加的Firebase Auth用户需完成手机号验证流程,仅添加账号未验证会触发验证提示。
4. AuthStateListener逻辑优化
延迟启动后先检查当前用户状态,若已登录则直接进入用户信息检查流程,无需等待AuthStateListener触发,提升启动效率。
内容的提问来源于stack exchange,提问作者Irakli Gvelesiani
相关产品推荐
相关产品推荐

