【发布时间】:2017-03-02 07:41:10
【问题描述】:
我正在学习使用 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
现在,我正在尝试列出 David 参与的聊天。所以我执行以下操作:
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。但是,由于我想显示用户名,而不是 uId,我必须再次从另一个节点检索数据。这是我的担心,因为我必须添加另一个异步侦听器来从不同的节点检索数据。如果它是 MySQL 之类的东西,那不会有问题,但 Firebase 监听器是异步的。这种异步侦听器检索数据的想法非常令人困惑,并且想知道我是否做得对。我应该在这里做什么?
【问题讨论】:
-
乍一看这看起来不错:您正在客户端上循环以“加入”数据库中的用户数据。有什么问题?
-
当我使用异步侦听器循环用户数据时,是否保证按顺序返回值?换句话说,当第一个侦听器运行时,第二个侦听器会立即运行,无论第一个侦听器是否返回值,因为它的任务是异步的。所以我想知道是否多个侦听器是异步运行的,是否有可能将返回的值无序地添加到数组列表中?
-
所有到数据库的流量都通过同一个套接字,所以它们都是按顺序执行的。请参阅 this answer 以了解有关流水线的更多信息。
-
这回答了我的问题!非常感谢弗兰克 :)
标签: android firebase firebase-realtime-database