Android Java开发 Firebase实时数据库自动生成push ID引用取值问题
错误原因
你之前的代码逻辑存在两个核心问题:
- 指向
Data/{用户ID}/Traffic/Wedding节点的引用,调用myRef.getKey()拿到的是Wedding节点自身的key,并非其下挂载的自动生成push ID - 额外执行
myRef.child(uid)后,最终引用路径会偏移为Wedding/Wedding这个不存在的节点,自然无法读到stData1~stData4的目标取值
可直接落地的实现方案
结合你提供的数据库JSON结构,分两种常见业务场景提供可直接复用的代码:
场景1:读取Wedding节点下所有自动ID关联的数据集
适配Wedding节点下可能存在多条push数据的场景,无需提前知晓具体的push ID字符串:
// 引用直接定位到Wedding节点,不需要额外拼接子节点 DatabaseReference myRef = myfire.getReference() .child("Data") .child(strUID) .child("Traffic") .child("Wedding"); myRef.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // 遍历Wedding下所有自动生成的push ID节点 for (DataSnapshot autoIdSnapshot : dataSnapshot.getChildren()) { // 当前autoIdSnapshot对应的就是JSON里-MYKeSN8GZ8WbI-8TfVB这类自动ID节点 if (autoIdSnapshot.getValue() == null) { Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show(); continue; } // 直接从当前push ID节点下提取字段值 String stData1 = Objects.requireNonNull(autoIdSnapshot.child("stData1").getValue()).toString(); String stData2 = Objects.requireNonNull(autoIdSnapshot.child("stData2").getValue()).toString(); String stData3 = Objects.requireNonNull(autoIdSnapshot.child("stData3").getValue()).toString(); String stData4 = Objects.requireNonNull(autoIdSnapshot.child("stData4").getValue()).toString(); // 原有业务逻辑保持不变 category basic = new category(stData1, stData2, stData3, stData4); tvBalance.setText(stData4); } } @Override public void onCancelled(@NonNull DatabaseError error) { // 可按需补充读取失败的提示逻辑 Toast.makeText(getApplicationContext(), "数据读取失败:" + error.getMessage(), Toast.LENGTH_SHORT).show(); } });
场景2:仅需获取最新一条push ID对应的数据集
如果业务只需要取Wedding下最后一次push存入的那条数据,可通过查询条件直接定位,无需遍历全部节点:
DatabaseReference myRef = myfire.getReference() .child("Data") .child(strUID) .child("Traffic") .child("Wedding"); // 按push ID的生成规则排序,取最后一条数据 myRef.orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot snapshot : dataSnapshot.getChildren()) { String stData4 = Objects.requireNonNull(snapshot.child("stData4").getValue()).toString(); tvBalance.setText(stData4); } } @Override public void onCancelled(@NonNull DatabaseError error) { } });
实用注意点
- 如果业务需要精准定位某一条历史push数据,需要在当初调用
push()生成ID的时机,把对应的自动ID手动存储(比如存在本地SP、或者用户节点的其他子字段),后续直接用存储的ID拼接引用路径即可,无需动态遍历 - 提取节点值时建议增加空值判断,避免数据未同步完成时触发空指针崩溃
内容的提问来源于stack exchange,提问作者user14253444
相关产品推荐
相关产品推荐

