You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase应用登录后关闭再重启,执行注销操作后闪退如何解决?

问题根因

核心是空指针异常,触发原因如下:

  • SignupTabFragment中调用addSnapshotListener注册Firestore文档监听时,没有绑定组件生命周期,也没有做异常、空值校验
  • 该监听器是永久有效的,即便所属Fragment/Activity销毁也会持续接收回调
  • 你执行注销操作后,Firebase Auth状态变更,之前监听的用户文档因为鉴权失败会返回异常,此时onEvent回调返回的value为null,代码直接调用value.getString("userType")触发空指针导致闪退
  • 首次登录注销不闪退是因为首次运行时注销跳转后进程很快释放,监听器来不及触发回调;重启应用后进程生命周期更长,注销后监听器触发就会命中异常

修复方案

1. 修改SignupTabFragment的监听逻辑

给监听器绑定Fragment生命周期,同时添加空值、异常判断:

if(firebaseAuth.getCurrentUser() != null){
    // 从Firebase拉取用户数据
    userIDFireStore = firebaseAuth.getCurrentUser().getUid();
    DocumentReference documentReference = firestore.collection("users").document(userIDFireStore);
    // 第一个参数传入Fragment自身作为LifecycleOwner,Fragment销毁时自动解绑监听器
    documentReference.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
        @Override
        public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
            // 优先拦截异常、空数据、Fragment已销毁的场景
            if (error != null || value == null || getActivity() == null) {
                return;
            }
            userTypeFirestore = value.getString("userType");
            // 调整equals写法避免userType为空时触发空指针
            if("Admin".equals(userTypeFirestore)){
                startActivity(new Intent(getActivity().getApplicationContext(),AdminHomeActivity.class));
                getActivity().finish();
            }
            if("Student".equals(userTypeFirestore)){
                startActivity(new Intent(getActivity().getApplicationContext(),HomeActivity.class));
                getActivity().finish();
            }
        }
    });
}

2. 可选优化(避免潜在异常)

移除HomeActivity中onKeyDown方法里的System.exit(0),Android平台不推荐直接杀死进程,调用finish()就足够关闭当前Activity,强制杀进程可能导致资源释放异常。

内容的提问来源于stack exchange,提问作者Krutarth Vaishnav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:39:03