【问题标题】:Firebase DataSnapshot, Can't retrieve the right list of childrenFirebase DataSnapshot,无法检索正确的孩子列表
【发布时间】:2018-04-01 20:20:06
【问题描述】:

我有一个用于聊天应用程序的数据库结构,所以我在数据库中有一个消息节点,如下所示

messages 是包含两个聊天用户的 UID 的键的父级,该键包含聊天正文的值,我的应用程序在按我想要的方式推送数据时运行良好。

但是当试图读取数据时,DataSnapShot 对象总是有节点的最后一个叶子表示键的子节点。我尝试了不同的方法来获取它自己迭代的密钥并获得它的值列表,但没有运气。

我尝试过的方法

  public static final String MESSAGES_NODE_DB = "messages"; 
  mMessageDbRef = FirebaseDatabase.getInstance().getReference()
                    .child(MESSAGES_NODE_DB).child(keyUserA + "-" + KeyUserB);
    
     mMessageDbRef.addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    Timber.d("parent key " + dataSnapshot.getKey());
    
                    for (DataSnapshot singleSnap : dataSnapshot.getChildren()) {
                            Message message = singleSnap.getValue(Message.class);
                            messageList.add(message);
                            instantiateRecyclerView();
                    }
                }

这种方法总是会导致错误 Can't convert object of type

java.lang.String

父键打印 L91eMRVq_nx6WHUzZFo

另一个

    mMessageDbRef = FirebaseDatabase.getInstance().getReference().child("messages");
for (DataSnapshot singleSnap : dataSnapshot.getChildren()) {
                Timber.d("keys" + singleSnap.getKey());
            }
        }

输出是 L91eMRVq_nx6WHUzZFo

我想要达到的目标

将消息节点内的键列表检索为

vXgRtbjqhUYPOLyjhmGKRzITUC83-24L0kQx75fhoz06YpXnWRheETct2

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    在 onChildAdded 方法内部不要使用 getChildren() 和 for 循环方法,因为 onChildAdded 方法返回 mMessageDbRef 引用下方的各个节点。基本上 onChildAdded 中的数据快照参数可以直接转换为 Message 对象。

    因此,像您所做的那样直接将数据快照值分配给消息对象,而无需使用任何循环或 getChildren 方法。

    通过这样做,您将可以通过消息对象变量访问消息的值。

    类似这样的:

    @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    
                            Message message = dataSnapshot.getValue(Message.class);
                            messageList.add(message);
                            instantiateRecyclerView();
                    }
                }
    

    【讨论】:

    • 确实有效,谢谢,虽然我正在为用户创建另一个节点,看起来像这样 /users/{$userId}/value.. 我在节点用户上使用迭代并得到孩子们没有任何问题,你能帮我解释一下有什么区别吗?
    • 你在用户节点上附加了什么监听器?是 childEventListener 吗?
    • ValueEventListener 那一个,是不是假设不同EventListener监听特定的节点,为什么会有不同的表现?
    【解决方案2】:

    要检索messages 节点内的密钥:

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("messages").child(keyUserA + "-" + KeyUserB);
    
    reference.addListenerForSingleValueEvent(new ValueEventListener() {
     @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
    for(DataSnapshot datas: dataSnapshot.getChildren()){
       String keys=datas.getKey();
        }
     }
     @Override
    public void onCancelled(DatabaseError databaseError) {
       }
     });
    

    datasnapshot 位于 child(keyUserA + "-" + KeyUserB);,然后您在随机 ID L91eMRVq_nx6WHUzZFo 中进行迭代,您将能够使用 getKey() 检索它

    【讨论】:

    • 这个想法是获取包含两个 uid 的节点并遍历快照将得到推送 id 的子代,正如 vivek 所说,感谢您的评论,尽管非常感谢。
    • 迭代会得到这个L91eMRVq_nx6WHUzZFo,正如解释的那样,你想得到什么ID?
    • 问题是关于获取消息节点的直接子节点用“-”分隔的长 2 个字符串键而不是其中的推送 id
    • 然后将快照放在child("messages") 并迭代并使用getKey(),您将能够获得以“-”分隔的键列表
    • 我试过这种方法,也有问题,让我更新一下我的问题
    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    相关资源
    最近更新 更多