Java从Firebase获取Long类型WeeklyDate值报空指针异常排查
问题根因
- 空指针和取值错误的核心原因是Firebase数据监听是异步执行的:调用
addValueEventListener注册监听后,网络请求拉取数据在后台线程执行,后续主线程代码不会等待数据返回就会立刻执行。 - 未初始化
weeklyDate时,回调还没触发赋值,变量为null,执行new Date(weeklyDate)会触发自动拆箱,调用null对象的longValue()方法,直接抛出你看到的空指针异常。 - 你给
weeklyDate设置初始值0L/1L后,空指针消失,但此时执行日期转换逻辑时,回调还没拿到Firebase的真实数据,用的是你写的初始值,自然计算结果不符合预期。等回调真正拿到Firebase返回的时间戳赋值时,周数判断、UI渲染逻辑早就执行完了,赋值操作不会生效。 - 代码里还有两个隐藏bug:字符串内容比较用了
==(实际比较内存地址,会导致内容匹配失败)、onCancelled回调留空无法排查拉取失败问题。
修复方案
- 所有依赖
weeklyDate、weeklyPost返回值的业务逻辑,全部移动到onDataChange回调内部,保证拿到真实数据后再执行计算和UI渲染。 - 增加节点存在性校验,避免节点缺失时触发空指针。
- 修复字符串比较、空回调等隐藏bug。
- 后续记得在View回收时移除监听,避免内存泄漏。
修正后核心代码
firebaseDatabase = FirebaseDatabase.getInstance(); databaseReference = firebaseDatabase.getReference(); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { // 先校验节点是否存在,避免空指针 if (!snapshot.hasChild("WeeklyDate") || !snapshot.hasChild("WeeklyPost")) { Log.e("Firebase", "Weekly配置节点不存在"); return; } // 读取Firebase真实值 weeklyDate = snapshot.child("WeeklyDate").getValue(Long.class); weeklyPost = snapshot.child("WeeklyPost").getValue(String.class); // 所有依赖返回值的逻辑全部放在回调内执行 if (randomMixList.size() > 0){ final int random = new Random().nextInt(randomMixList.size()); ArrayList<HomeMixData> weekly_list = new ArrayList<>(); weekly_post = randomMixList.get(random); Date currentDate = new Date(System.currentTimeMillis()); Calendar calendar = Calendar.getInstance(); calendar.setFirstDayOfWeek(Calendar.MONDAY); calendar.setMinimalDaysInFirstWeek(4); calendar.setTime(currentDate); int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR); Log.e("Week", "Current"+currentWeek); Date storedDate = new Date(weeklyDate); calendar = Calendar.getInstance(); calendar.setTime(storedDate); int storedWeek = calendar.get(Calendar.WEEK_OF_YEAR); Log.e("Week", "Stored"+storedWeek); if (currentWeek != storedWeek){ homeMix.setWeekly(weekly_post); Log.e("beef", "false"); } else{ for(HomeMixData i : randomMixList){ // 字符串内容比较用equals,不要用== if (i.postID.equals(weeklyPost)){ weekly_post = i; Log.e("beef", "true"); } } } weekly_list.add(weekly_post); if (weekly_post.identifier) { weekly_title.setText(weekly_post.hcstallname); weekly_author.setText("By: "+weekly_post.hcauthor); Picasso.get().load(weekly_post.hccoverimg).into(weekly_img); } else{ weekly_title.setText(weekly_post.recipeName); weekly_author.setText("By: "+weekly_post.userName); Picasso.get().load(weekly_post.foodImage).into(weekly_img); } } } @Override public void onCancelled(@NonNull DatabaseError error) { // 不要留空,打印错误方便排查 Log.e("Firebase", "拉取Weekly配置失败", error.toException()); } }); // 回调外部不要写任何依赖weeklyDate/weeklyPost的逻辑,这里执行时数据还未返回
内容的提问来源于stack exchange,提问作者beefwhale
相关产品推荐
相关产品推荐

