处理Firebase中的异步侦听器以检索数据

时间:2016-10-20 10:43:04

标签: android firebase firebase-realtime-database

我正在学习使用Firebase,想知道我是否正确行事。如果我理解正确,您只能使用Firebase中的侦听器异步检索数据。我将尝试用一个例子来解释我的问题。假设我有一个简单聊天应用程序的以下数据库数据:

chat_info:
  chatID_1:
    participants:
      uId_1: true
      uId_2: true

users:
  uId_1:
    display_name: "David"
    participated_chats:
      chatID_1: true
      chatID_2: true
  uId_2:
    display_name: "Jason"
    participated_chats:
      chatID_1: true
      chatID_2: true

现在,我正在尝试列出大卫参与的聊天。所以我做了类似以下的事情:

    ArrayList<String> chatIdList = new ArrayList<String>();
    // Retrieve chat Ids of participating chats
    usersRef.child(mFirebaseUser.getUid()).child("participated_chats").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            chatIdList.clear();

            // Save each chat Id to an arraylist
            for (DataSnapshot child : dataSnapshot.getChildren()) {
                chatIdList.add(child.getKey());

                // when loop hits the last user of the dataSnapsot
                if(chatIdList.size() >= dataSnapshot.getChildrenCount()) {

                    // For each chat Id, retrieve participants' uIds
                    for(String chatId : chatIdList) {
                        chatInfoRef.child(chatId).addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                Chat chat = dataSnapshot.getValue(Chat.class);  // In a Chat class, there is public Map<String, Boolean> participants = new HashMap<>();
                                chatDetailList.add(chat);
                                chatListAdapter.notifyDataSetChanged();
                            }
                            @Override
                            public void onCancelled(DatabaseError databaseError) {}
                        });

                    }
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

现在,我有用户参与的每个聊天的参与者用户。但是,由于我想显示用户名而不是uId,我必须再次从另一个节点检索数据。这是我的担心,因为我必须添加另一个异步列表器来从不同节点检索数据。如果它像MySQL一样,它不会是一个问题,但Firebase监听器是异步的。异步监听器检索数据的这种想法非常令人困惑,并且想知道我是否做得对。我该怎么办?

1 个答案:

答案 0 :(得分:1)

您可以将第一个侦听器附加到/users/uId_1以获取整个用户对象,然后您只需从dataSnapshot值中获取用户的用户名/显示名称。

这是一个例子。

ArrayList<String> chatIdList = new ArrayList<String>();
// Retrieve chat Ids of participating chats
usersRef.child(mFirebaseUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        chatIdList.clear();

        User user = dataSnapshot.getValue(User.class);
        String username = user.getDisplay_name();

        Map<String, Boolean> participated_chats = user.getParticipated_chats();
        // Save each chat Id to an arraylist
        for (Map.Entry<String, Boolean> child : participated_chats.entries()) {
            chatIdList.add(child.getKey());

            // ... continues
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});