Android Studio中App获取Firestore用户数据时崩溃问题如何解决
崩溃原因
- 未做非空校验触发空指针:Firestore回调中没有判断返回异常、文档是否存在、
userType字段是否为空,当出现网络波动、文档缺失、字段不存在的情况时,userTypeFirestore为null,调用equals()方法直接崩溃。 - 生命周期不兼容:回调触发时如果Fragment已经和Activity解绑,
getActivity()返回null,调用页面跳转、Activity销毁方法会直接崩溃。 - 监听器使用不当:使用持续监听的
addSnapshotListener却没有做移除处理,跳转后监听器依然存活,后续回调触发时上下文失效也会导致崩溃。
修复方案
建议优先改用单次读取的get()方法替代实时监听(判断用户类型不需要持续监听),同时补充全链路非空校验和生命周期判断,修改后的代码如下:
if(firebaseAuth.getCurrentUser() != null){ userIDFireStore = firebaseAuth.getCurrentUser().getUid(); DocumentReference documentReference = firestore.collection("users").document(userIDFireStore); // 改用单次读取,避免监听器泄露 documentReference.get().addOnCompleteListener(task -> { // 优先判断Fragment是否仍依附于Activity,上下文无效直接终止逻辑 if (!isAdded() || getActivity() == null) { return; } // 判断读取任务是否成功 if (task.isSuccessful()) { DocumentSnapshot document = task.getResult(); // 判断文档是否存在 if (document != null && document.exists()) { userTypeFirestore = document.getString("userType"); // 字符串常量在前,避免空指针异常 if ("Admin".equals(userTypeFirestore)) { startActivity(new Intent(getActivity().getApplicationContext(), AdminHomeActivity.class)); getActivity().finish(); } else if ("Student".equals(userTypeFirestore)) { startActivity(new Intent(getActivity().getApplicationContext(), HomeActivity.class)); getActivity().finish(); } } } }); }
额外注意
如果业务场景确实需要使用实时监听addSnapshotListener,需要在Fragment的onStop()或onDestroyView()生命周期方法中手动调用ListenerRegistration.remove()方法移除监听器,避免内存泄露和无效回调。同时请检查Firestore安全规则,确保已登录用户有权限读取自己的users集合文档,避免权限拒绝导致读取失败。
内容的提问来源于stack exchange,提问作者Krutarth Vaishnav
相关产品推荐
相关产品推荐

