Android Studio外运行App触发Firebase相关NullPointerException求助
问题原因
崩溃的核心是异步操作执行顺序错误:
signInWithEmailAndPassword是异步方法,调用后会立即返回,实际登录验证需要等待网络请求完成- 你在调用登录方法后,立刻同步执行
FirebaseUtil.currentUserDetails(),此时FirebaseAuth还未完成登录流程,currentUserId()返回null - 而
currentUserDetails()中用!!强制将null转为非空字符串,直接触发NullPointerException
Android Studio内运行无异常是因为调试环境可能保留了之前的登录会话,FirebaseAuth.getInstance().uid不为空;外部冷启动时没有缓存的登录状态,就暴露了这个问题。
解决方案
1. 调整代码执行顺序,确保登录成功后再操作Firestore
将写入Firestore的代码移到登录成功的回调内部,保证获取用户ID时登录已完成:
mAuth.signInWithEmailAndPassword(User.getEmail()!!, User.getPassword()!!) .addOnCompleteListener(this) { task -> if (task.isSuccessful) { Log.d("Test", "signInWithEmail:success") val user = mAuth.currentUser // 登录成功后再执行Firestore数据写入 FirebaseUtil.currentUserDetails().set(User).addOnCompleteListener(this){ firestoreTask -> if (firestoreTask.isSuccessful) { Log.d("Test", "Insert data success") } else { Log.w("Test", "insert data failed", firestoreTask.exception) } } } else { Log.w("Test", "signInWithEmail:failure", task.exception) } }
2. 优化FirebaseUtil工具类,避免强制非空引发崩溃
修改工具类代码,增加空值判断,返回可空的DocumentReference,从根源避免空指针:
fun currentUserId(): String? { return FirebaseAuth.getInstance().uid // Kotlin推荐用属性代替getter方法 } fun currentUserDetails(): DocumentReference? { val userId = currentUserId() return userId?.let { FirebaseFirestore.getInstance().collection("users").document(it) } }
调用时也需要处理空值情况:
FirebaseUtil.currentUserDetails()?.set(User)?.addOnCompleteListener(this){ task -> if (task.isSuccessful) { Log.d("Test", "Insert data success") } else { Log.w("Test", "insert data failed", task.exception) } } ?: run { Log.w("Test", "用户未登录,无法写入数据") }
内容的提问来源于stack exchange,提问作者QuinRa
相关产品推荐
相关产品推荐

