Firebase / Android - 等待所有线程完成响应

Firebase / Android - Wait for all thread finish for response

我有以下代码:

public synchronized void next(final RoomListQueryResultHandler handler) {
    this.setLoading(true);

    roomList = new ArrayList<Room>();
    this.database.child("members").child(this.mUser.getUid()).child("rooms")
            .limitToFirst(this.mLimit)
            .startAt(this.currentPage * this.mLimit)
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    RoomListQuery.this.setLoading(false);
                    //mListAdapter.setLoading(false);

                    if (!dataSnapshot.hasChildren()) {
                        RoomListQuery.this.currentPage--;
                    }
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        Room room = ds.getValue(Room.class);
                        //roomList.add(Room.upsert(room));
                        Room.getRoom(room.getId(), new Room.RoomGetHandler() {
                            @Override
                            public void onResult(Room room, customException e) {
                                if (e != null) {
                                    // Error!
                                    e.printStackTrace();
                                    return;
                                }

                                roomList.add(room);
                            }
                        });
                        handler.onResult(roomList, (customException) null);
                    }

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    handler.onResult((List) null, new customException(databaseError.toString()));
                }
            });
     }
}

如果他们看到了,我有两个处理程序,首先我从 Firebase 调用 "rooms" 的列表,然后我在其他查询中获取每个处理程序的详细信息。

问题是响应是一个空列表,因为函数不等待房间的所有查询细节被执行,所以变量 roomList 总是 returns 空。

知道我可以实现什么,或者可以使用什么其他方法来解决它?

非常感谢! 你好。

根据您的应用程序的结构,您可能希望更改数据库设计,这样就无需为从第一个查询中检索到的每个房间执行额外的 Firebase 查询。

//mListAdapter.setLoading(false);

如果您要创建一个列表视图,其中每一行都来自 /members/<user_id>/rooms Firebase 节点,那么显示该列表所需的最小房间属性是什么?如果只是房间名称、照片 url、所有者、room_id 等几项内容,您最好从原始来源复制这些内容。然后单击这些行之一可以触发您作为 Room.getRoom(room.getId(), new Room.RoomGetHandler() { ... }); 的一部分的原始 附加 Firebase 查询,以导航到新屏幕/一次显示包含完整房间详细信息的模式检索到。

更新

为了解决您关于需要额外数据的评论,在这种情况下,作为 Room class 的一部分,我将包含一个额外的布尔值 _loadedDetails,最初设置为 false。因此,为了在列表中渲染一个房间,当 _loadedDetails 当前为 false 时,只显示一个加载微调器。这样您仍然可以执行那些额外的查询,并在完成后根据索引更新 roomList 内的适当 Room 对象。像这样:

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    RoomListQuery.this.setLoading(false);
    //mListAdapter.setLoading(false);
    if (!dataSnapshot.hasChildren()) {
        RoomListQuery.this.currentPage--;
    }
    int i = 0;
    for (DataSnapshot ds : dataSnapshot.getChildren()) {
        Room room = ds.getValue(Room.class);
        roomList.add(room); // here instead
        updateRoom(room, i);
        i++;
    }
    handler.onResult(roomList, (customException) null);
}

...
// outside of the ValueEventListener
public void updateRoom(room, index) {
    Room.getRoom(room.getId(), new Room.RoomGetHandler() {
        @Override
        public void onResult(Room room, customException e) {
            if (e != null) {
                // Error!
                e.printStackTrace();
                return;
            }
            room._loadedDetails = true; // make that publicly accessible boolean, or include a setter method instead
            roomList.set(index, room);
        }
    });
}