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

登录时获取Firebase用户信息,登出时忽略逻辑遇空指针异常问题

解决登出时的Firebase空指针异常问题

嘿,这个空指针问题很典型,我来帮你捋清楚!

问题根源

你遇到的Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference错误,核心原因是:用户登出后,FirebaseAuth的currentUser会变为null,但你在数据库监听的代码里直接调用了:

dbReference.child("AllUsers").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("profile")...

这里没有先判断currentUser是否存在,直接调用getUid()就触发了空指针。

另外,你虽然提前获取了firebaseUser并赋值了currentUserId,但后续数据库操作并没有复用这个变量,反而重复调用FirebaseAuth.getInstance().getCurrentUser(),既冗余又增加了出错风险。

修复方案

我们需要分登录状态和登出状态分别处理逻辑,并且确保所有访问Firebase用户信息的操作都先做null检查。

修正后的完整代码

String userID;
String currentUserId;
FirebaseAuth mAuth;
String mDayGreet;
String weekDay;
DatabaseReference dbReference = FirebaseDatabase.getInstance().getReference();
public static final String USER_ID_EXTRA_KEY = "EXTRA_KEY";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
    
    userID = getActivity().getIntent().getStringExtra(USER_ID_EXTRA_KEY);
    mAuth = FirebaseAuth.getInstance();
    FirebaseUser firebaseUser = mAuth.getCurrentUser(); // 只获取一次,避免重复调用
    TextView greeting = view.findViewById(R.id.greeting);
    TextView dayInfo = view.findViewById(R.id.info);

    // 先处理星期和时段的基础逻辑(不管登录状态都需要)
    Calendar mCalendar = Calendar.getInstance();
    SimpleDateFormat mFormatDate = new SimpleDateFormat("HH");
    String mDateString = mFormatDate.format(mCalendar.getTime());
    int time = Integer.parseInt(mDateString);
    int dayOfWeek = mCalendar.get(Calendar.DAY_OF_WEEK);

    if (Calendar.MONDAY == dayOfWeek) {
        if (time >= 0 && time < 18) {
            weekDay = getString(R.string.monday);
        }
    }
    dayInfo.setText(weekDay != null ? weekDay : ""); // 避免weekDay未赋值导致的空指针

    // 分登录/登出状态处理问候语
    if (firebaseUser != null) {
        currentUserId = firebaseUser.getUid();
        // 登录状态下才访问数据库获取用户名
        dbReference.child("AllUsers").child(currentUserId).child("profile").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                User userDetail = dataSnapshot.getValue(User.class);
                if (time >= 0 && time < 12) {
                    mDayGreet = getString(R.string.morning) + " " + (userDetail != null ? userDetail.getFirstName() : "");
                } else {
                    // 可补充下午、晚上等其他时段的逻辑
                    mDayGreet = getString(R.string.afternoon);
                }
                greeting.setText(mDayGreet);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                // 别忘了处理数据库访问失败的情况
                greeting.setText(getString(R.string.morning));
            }
        });
    } else {
        // 登出状态下直接显示不带名字的问候语
        if (time >= 0 && time < 12) {
            mDayGreet = getString(R.string.morning);
        } else {
            mDayGreet = getString(R.string.afternoon);
        }
        greeting.setText(mDayGreet);
    }

    return view;
}

关键修改点

  • 提前做null检查:在访问currentUser的任何属性前,先判断firebaseUser != null,只有登录状态才去访问数据库。
  • 复用firebaseUser变量:避免重复调用FirebaseAuth.getInstance(),减少冗余和潜在错误。
  • 处理null安全:比如dayInfo.setText(weekDay != null ? weekDay : ""),防止weekDay未赋值导致的空指针;还有userDetail != null的判断,避免数据库返回null时出错。
  • 拆分逻辑:把星期/时段的基础逻辑和登录状态的逻辑分开,代码结构更清晰。

这样修改后,登出状态下不会再去调用getUid(),自然就不会触发空指针异常了,同时也提升了代码的健壮性。

内容的提问来源于stack exchange,提问作者Mbuodile Obiosio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:44:15