使用Firebase PhoneAuth时Firestore用户数据被还原为默认值是什么原因?
问题根因
- 用户存在性查询逻辑不合理,且存在查询失败误判风险:你当前使用集合级
whereEqualTo查询匹配UID的文档属于冗余操作,users集合的文档ID本身就是用户UID,直接查询指定ID的文档即可。网络波动、本地缓存异常时,集合查询可能错误返回空结果,触发注册逻辑用默认值覆盖已有文档字段。 - 缺少前置登录状态校验:SplashScreen跳转时未先判断FirebaseAuth是否存在有效登录用户,直接跳转到短信登录页,老用户可能被引导重复走验证流程,大幅提升误触发覆盖的概率。
- 数据写入存在隐式覆盖风险:如果你的User数据类未显式赋值的字段默认值为null,且开启了Firestore null值序列化配置,即使用
SetOptions.merge(),这些null字段也会覆盖数据库中已有的非空值。 - 存在逻辑代码错误:OTP验证判断
if (otp.isNotEmpty() || otp.length != 6)逻辑错误,会导致不符合规则的OTP也触发验证流程。
修复方案
- 优化用户存在性校验逻辑,改用文档直接查询,且不要空吞异常:
fun checkIfUserAlreadyExist( activity: SigninWithPhoneActivity, userId: String, userDetails: User ) { mFireStore.collection("users").document(userId) .get() .addOnSuccessListener { document -> if (document.exists()) { activity.userSignInSuccess() } else { FirestoreClass().registerUser(activity, userDetails) } } .addOnFailureListener { e -> Toast.makeText(activity, "登录状态校验失败,请重试", Toast.LENGTH_LONG).show() } }
- 在SplashScreen添加登录状态前置判断,已登录用户直接进入业务页,无需走短信验证流程:
// SplashScreen onCreate逻辑中添加 val currentUser = FirebaseAuth.getInstance().currentUser if (currentUser != null) { startActivity(Intent(this, ServiceAreaActivity::class.java)) finish() } else { startActivity(Intent(this, SigninWithPhoneActivity::class.java)) finish() }
- 优化注册写入逻辑,仅传入初始化必要字段,避免全对象写入带来的隐式覆盖:
private fun registerUser(activity: SigninWithPhoneActivity, userInfo: User) { val initFields = mapOf( Constants.USER_ID to userInfo.user_id, "user_type" to "customer", "mobile" to userInfo.mobile ) mFireStore.collection(Constants.USERS) .document(userInfo.user_id) .set(initFields, SetOptions.merge()) .addOnSuccessListener { activity.userRegistrationSuccess() } .addOnFailureListener { e -> activity.hideProgressDialog() Toast.makeText(activity, "注册失败,请重试", Toast.LENGTH_LONG).show() } }
- 修复OTP验证逻辑错误:
binding.btnSignIn.setOnClickListener { val otp = binding.etOtp.text.toString().trim() if (otp.isNotEmpty() && otp.length == 6) { verifyVerificationCode(otp) } else { Toast.makeText(this, "请输入收到的6位OTP验证码", Toast.LENGTH_LONG).show() } }
内容的提问来源于stack exchange,提问作者Codist
相关产品推荐
相关产品推荐

