向FirebaseDatabase添加数据时布尔值触发空指针异常的排查求助
Hey there, let's break down why you're hitting that NullPointerException and how to fix it.
The core issue here is that you're writing data to Firebase in two separate setValue() calls: first you write the Name and Key, then you write IsSelected as a separate operation. Firebase Realtime Database triggers listeners as soon as any part of the data changes. So when the first setValue() completes, your listener fires, but at that point the IsSelected node doesn't exist yet—so dataSnapshot.child("IsSelected").getValue() returns null, and casting that directly to Boolean throws the NPE. By the time you restart the app, both writes have finished, so all data is present and everything works.
Here are two solid solutions to fix this:
1. Write all data atomically (recommended)
Instead of splitting the write into two steps, include IsSelected directly in your initial data map. This ensures the entire node is written at once, so your listener only triggers when all data is ready. Note that we'll switch the HashMap's generic type to <String, Object> since we're mixing String and Boolean values:
String key = mDairyDataBase.push().getKey(); HashMap<String, Object> dataMap = new HashMap<>(); dataMap.put("Name", item); dataMap.put("Key", key); dataMap.put("IsSelected", false); // Add this to the map upfront mDairyDataBase.child(key).setValue(dataMap);
2. Add null safety checks in your read logic
If you can't modify the write logic (e.g., for legacy data reasons), you can guard against null values when reading IsSelected. Here's how to do it safely:
HashMap<String, String> value = (HashMap<String, String>) dataSnapshot.getValue(); if(value != null){ String name = value.get("Name"); String key = value.get("Key"); // Check if the IsSelected node exists and has a valid value Boolean isSelected = dataSnapshot.child("IsSelected").getValue(Boolean.class); // Fallback to false if the value is null or the node doesn't exist boolean selectedState = isSelected != null ? isSelected : false; mModelList.add(new Model(name, key, selectedState)); }
Alternatively, you can first check if the node exists with dataSnapshot.hasChild("IsSelected") for extra clarity:
HashMap<String, String> value = (HashMap<String, String>) dataSnapshot.getValue(); if(value != null){ String name = value.get("Name"); String key = value.get("Key"); boolean isSelected = false; if(dataSnapshot.hasChild("IsSelected")){ Boolean selected = dataSnapshot.child("IsSelected").getValue(Boolean.class); isSelected = selected != null ? selected : false; } mModelList.add(new Model(name, key, isSelected)); }
The first approach is better because it eliminates the root cause—partial data being read before the write is complete. The second approach is a robust fallback if you need to handle existing data or can't adjust the write flow.
内容的提问来源于stack exchange,提问作者Kristofer

