登录时获取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
相关产品推荐
相关产品推荐

