Firebase数据库onChildChangeListener获取name值为null求助
问题根源
你用addChildEventListener监听child("userID").child(id).child("Personal Information")节点时,onChildChanged回调里的dataSnapshot对应的是该节点下发生变化的子节点本身,而非整个Personal Information父节点。
比如当name字段更新时,dataSnapshot就是name这个节点的快照,此时你调用dataSnapshot.child("name")相当于在name节点下找子节点name,自然找不到对应数据,导致返回null。而address能成功获取,是因为当address字段变化时,dataSnapshot指向address节点,你调用dataSnapshot.child("address")其实是错误操作,但可能刚好触发了其他逻辑?不对,实际核心是你混淆了ChildEventListener和ValueEventListener的快照范围。
修复后的代码
直接从dataSnapshot本身获取子节点的key和值即可:
databaseReference.addChildEventListener(new ChildEventListener() { @Override public void onChildChanged(@NonNull DataSnapshot dataSnapshot, String previousChildName) { // dataSnapshot就是当前发生变化的子节点(比如name或address) String key = dataSnapshot.getKey(); // 直接拿到子节点的键名,比如"name" String value = dataSnapshot.getValue(String.class); // 直接拿到子节点的对应值 if (value != null) { Log.i("FirebaseDataChange", "Key: "+ key + " Value: " + value); } else { Log.e("FirebaseDataChange", "Value is null"); } } // 实现其他必填的回调方法 @Override public void onChildAdded(@NonNull DataSnapshot dataSnapshot, String previousChildName) {} @Override public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {} @Override public void onChildMoved(@NonNull DataSnapshot dataSnapshot, String previousChildName) {} @Override public void onCancelled(@NonNull DatabaseError databaseError) { Log.e("FirebaseError", databaseError.getMessage()); } });
额外优化:仅监听name字段的变更
如果只需要处理name字段的更新,可以在回调中增加键名判断:
@Override public void onChildChanged(@NonNull DataSnapshot dataSnapshot, String previousChildName) { String key = dataSnapshot.getKey(); if ("name".equals(key)) { String value = dataSnapshot.getValue(String.class); if (value != null) { Log.i("FirebaseDataChange", "Name Value: " + value); } else { Log.e("FirebaseDataChange", "Name value is null"); } } }
为什么addEventListener能正常工作?
你提到的addEventListener应该是指ValueEventListener,它的onDataChange回调拿到的是整个Personal Information节点的快照,所以需要用dataSnapshot.child("name")定位到具体字段。而ChildEventListener是针对子节点的变更触发,快照范围是单个子节点,这是两者的核心区别。
内容的提问来源于stack exchange,提问作者eMr8rlzs

