如何将Firebase数据转换为Java对象?

65
使用Firebase库以Message(String, String)的形式将数据发送到服务器,并将其添加到HashMap<String, Message>中。
示例:
Firebase fb = new Firebase(URL);
Firebase msgRef = fb.child("finished");
HashMap<String, Message> msgList = new HashMap<>();
Message msg = new Message(m, n);
msgList.put(HASHKEY, msg);
msgRef.push().setValue(msgList);

使用 Firebase 方法 addValueEventListener() 接收数据时,获取的字符串格式为

{ key = finished, value = {
    -Js9Rn0uttjYIGdcv8I1={Moosa={message=email, name=Kamran}},
    -Js9Vsmv6BnVzOzpl2L8={Moosa={message=msgs, name=Imran}}, 
    -Js9WtQ8yeDwVxQMFCZb={Moosa={message=samsung, name=Samad}}, 
    -Js9RarxoJPKn4RO2HaM={Moosa={message=Message, name=Moosa}}, 
    -Js9b6f75lwwbsqQNJz0={Moosa={message=Qmobile, name=Bilal}}, 
    -Js9aDxt8TlgTGUccuxu={Moosa={message=last, name=Moosa}}} }

我该如何将它转换为消息对象.....????

5个回答

126

有两种方法可以从Firebase DataSnapshot中获取数据,而不需要使用Map<String, Object>

第一种方法是使用DataSnapshot的方法遍历子节点:

ref = FirebaseDatabase.getInstance().getReference("messages").limitToLast(10);
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
            String name = (String) messageSnapshot.child("name").getValue();
            String message = (String) messageSnapshot.child("message").getValue();
        }
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) { }
});

在上面的代码片段中,我们使用getChildren()来获取您的消息的Iterable。然后,我们使用child("name")来获取每个特定的子属性。
第二种方法是使用内置的JSON-to-POJO序列化程序/反序列化程序。当您发送消息列表时,其中的Message对象将被序列化为JSON并存储在Firebase中。
要再次将它们取出,请执行相反的操作:
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
            Message message = messageSnapshot.getValue(Message.class);
        }
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) { }
});

在这个第二个片段中,我们仍然使用getChildren()来获取消息,但现在我们将它们从JSON反序列化回一个Message对象。
对于一个使用上述方法的简单示例应用程序,请查看 Firebase的AndroidChat示例。它还展示了如何有效地处理消息列表(提示:FirebaseListAdapter)。

2
在你的第二种方法中,Firebase 数据是如何映射到 POJO 的属性上的?POJO 属性名称和 Firebase 节点名称是否需要完全匹配? - Parag Kadam
2
@ParagKadam 是的,只要它们具有相同的字段名称。 - Moses Aprico
1
如果属性如“名称”和“消息”是动态的,怎么获取数据快照并生成一个对象。将Json对象直接转换为Java对象。 - Dushyant Suthar
1
你可以将值存储到 Map<String,Object> 中。但我建议不要这样做。如果对象是动态的,最好还是坚持使用 DataSnapshot 本身。 - Frank van Puffelen

11

所以如果你想要获取消息,可以按照以下步骤操作:

        for (DataSnapshot child : dataSnapshot.getChildren()){
    //child is each element in the finished list
    Map<String, Object> message = (Map<String, Object>)child.getValue();
    Message msg = new Message((String) message.getValue().get("message"),
            (String) message.get("name"));
}

在这两种情况下都返回了 null 值... dataSnapshot.getValue(); child.getValue(); - Moosa Baloch
你能展示一下你发送给Firebase的请求吗?另外,你是使用哪种方法来检索数据的,是onDataChange还是onChildAdded - M090009
Firebase msgRef = fb.child("messagebox"); HashMap<String, Message> msgList = new HashMap<>(); Message msg = new Message(m, n); msgList.put("Moosa", msg); msgRef.push().setValue(msgList); - Moosa Baloch
DATASNAPSHOT ---> {-Js9Rn0uttjYIGdcv8I1={Moosa={message=email, name=Kamran}}, -Js9Vsmv6BnVzOzpl2L8={Moosa={message=msgs, name=Imran}}, -Js9WtQ8yeDwVxQMFCZb={Moosa={message=samsung, name=Samad}}, -Js9RarxoJPKn4RO2HaM={Moosa={message=Message, name=Moosa}}, -Js9b6f75lwwbsqQNJz0={Moosa={message=Qmobile, name=Bilal}}, -Js9aDxt8TlgTGUccuxu={Moosa={message=last, name=Moosa}}} - Moosa Baloch
1
使用嵌套的for循环,并借助上述解决方案迭代子值,成功获取了它。谢谢兄弟。 - Moosa Baloch
显示剩余5条评论

9

通过嵌套的for循环迭代dataSnapshot的值并获取子级,然后迭代子元素以获取所需的值...

for (DataSnapshot child : dataSnapshot.getChildren()) {
                    for (DataSnapshot single : child.getChildren()) {
                        Map<String, Object> map = (Map<String, Object>) single.getValue();
                        String a = (String) map.get("message");
                        String b = (String) map.get("name");
                        textView.append(b + " -- " + a + "\n");
                    }
                }

6

如果您想使用Gson库将Firebase对象转换为JSON,请使用以下代码:

databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Object object = dataSnapshot.getValue(Object.class);
            String json = new Gson().toJson(object);
            Example example= new Gson().fromJson(json, Example.class);
            Log.e("json","json: " + example.getGlossary());
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

这将把完整的数据库结构转换成字符串JSON,然后使用Gson Lib将JSON转换为类对象。

2
你可以使用ChildEventListener而不是ValueEventListener来实现。例如,我有一个名为match的类,它有三个字符串属性{id,name,photoUrl},然后我将所有值添加到一个List中。与使用for循环不同,下面的代码对我有效。
    Query queryRef = mDatabase.child("users").child(user.getUid()).child("matches");

    ChildEventListener listener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
            Match match = dataSnapshot.getValue(Match.class);
            matchList.add(match);
            mAdapter = new MatchAdapter(getContext(), matchList);
            recyclerView.setAdapter(mAdapter);
        }
        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
            Log.d("MESSAGEFRAGMENT", "CHILDCHANGE");
        }
        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };
    queryRef.addChildEventListener(listener);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接