Firebase使用limitToLast(1)监听新消息时嵌套Snapshot无法解析为Message对象
问题原因
当你使用limitToLast(1)执行查询时,即使仅返回1条匹配结果,Firebase 会保留原节点的层级结构,返回的DataSnapshot外层会包裹消息的索引key(比如示例中的10),直接对该外层快照调用getValue(Message.class)无法匹配到Message类的对应字段,因此返回的所有字段都是null。
解决方案
方案1:直接提取快照的唯一子节点
limitToLast(1)的查询结果只会包含1个子节点,直接获取迭代器首个元素即可,无需提前知道子节点的key:
ref.child("messages").child(mConversation.getConversationId()).limitToLast(1).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (mRecyclerViewAdapter == null || !snapshot.exists()) { return; } // 直接获取唯一的消息子节点 DataSnapshot msgSnapshot = snapshot.getChildren().iterator().next(); Message message = msgSnapshot.getValue(Message.class); // 后续消息处理逻辑 } @Override public void onCancelled(@NonNull DatabaseError error) { // 错误处理逻辑 } });
方案2:改用ChildEventListener监听新增消息
如果你只是需要实时接收新增的消息,使用ChildEventListener会更适配该场景,回调返回的快照直接是消息节点,无需额外拆分层级:
ref.child("messages").child(mConversation.getConversationId()) .limitToLast(1) .addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(@NonNull DataSnapshot snapshot, String previousChildName) { // 此处snapshot直接对应消息节点,可直接解析 Message message = snapshot.getValue(Message.class); // 新增消息处理逻辑 } @Override public void onChildChanged(@NonNull DataSnapshot snapshot, String previousChildName) {} @Override public void onChildRemoved(@NonNull DataSnapshot snapshot) {} @Override public void onChildMoved(@NonNull DataSnapshot snapshot, String previousChildName) {} @Override public void onCancelled(@NonNull DatabaseError error) {} });
内容的提问来源于stack exchange,提问作者Brad Priddy
相关产品推荐
相关产品推荐

