Android 从firebase数据库获取多个值

Android 从firebase数据库获取多个值,android,firebase,firebase-realtime-database,android-asynctask,Android,Firebase,Firebase Realtime Database,Android Asynctask,在我们的数据库结构中,每个“用户”持有多个bid Id,每个bid Id代表“作业”数据库中的一个入口点。 当前,当我们想要迭代一个人的所有作业时,代码看起来类似于: final DatabaseReference mDatabaseJobs = FirebaseDatabase.getInstance().getReference().child("Jobs"); DatabaseReference mDatabaseUser = FirebaseDatabase.getIns

在我们的数据库结构中,每个“用户”持有多个bid Id,每个bid Id代表“作业”数据库中的一个入口点。
当前,当我们想要迭代一个人的所有作业时,代码看起来类似于:

final DatabaseReference mDatabaseJobs = FirebaseDatabase.getInstance().getReference().child("Jobs");
        DatabaseReference mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUser.getUid());
        mDatabaseUser.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                DataSnapshot userBids = dataSnapshot.child("listOfBids");
                final int num_user_bids = (int) userBids.getChildrenCount();

                for(final DataSnapshot job : userBids.getChildren()){
                    String jobId = job.getValue(String.class);
                    mDatabaseJobs.child(jobId).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            bid_count.addAndGet(1);
这是数据库结构,目标是以某种方式获取特定人员的所有工作

有没有办法一次检索所有作业?你有钥匙清单吗?而不是为每一个调用添加侦听器?
如果不是,我知道firebase异步获取数据,但它是并行的吗
i、 e我们当前递增一个原子整数,以了解firebase是否已获取所有作业,因为我们不希望线程同时递增计数器,在当前实现中是否有必要?

谢谢

您可以在“用户”之外保留一个HashMap,用当前用户的作业列表填充它。然后将另一个侦听器附加到“作业”上,并在hashMap上迭代,获取所需的特定作业。以下是参考代码:

HashMap<Integer, String> listOfJobs = new HashMap<>();
DatabaseReference mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUser.getUid()).child("listOfBids");

mDatabaseUser.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    if (dataSnapshot.exists) {
        listOfJobs.putAll((Map) dataSnapshot.getValue());
    }
    // Here you can add a listener to the entire "Jobs" reference like this
    DatabaseReference mDatabaseJobs = FirebaseDatabase.getInstance().getReference().child("Jobs");
    mDatabaseJobs.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot userDataSnapshot) {
            if (userDataSnapshot.exists) {
                for (String jobId : listOfJobs.values()) {
                    if (userDataSnapshot.hasChild(jobId) {
                        DataSnapshot job = userSnapshot.child(jobId);
                        // here you can use job snapshot
                        bid_count.addAndGet(1); // something like this?
                    }
                }
            }
        }

});
HashMap listOfJobs=newhashmap();
DatabaseReference mDatabaseUser=FirebaseDatabase.getInstance().getReference().child(“用户”).child(currentUser.getUid()).child(“listOfBids”);
mDatabaseUser.addListenerForSingleValueEvent(新的ValueEventListener()){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
if(dataSnapshot.exists){
putAll((Map)dataSnapshot.getValue());
}
//在这里,您可以向整个“Jobs”引用添加一个侦听器,如下所示
DatabaseReference mDatabaseJobs=FirebaseDatabase.getInstance().getReference().child(“作业”);
mDatabaseJobs.addListenerForSingleValueEvent(新的ValueEventListener()){
@凌驾
公共void onDataChange(DataSnapshot用户DataSnapshot){
if(userDataSnapshot.exists){
for(字符串jobId:listOfJobs.values()){
if(userDataSnapshot.hasChild(jobId){
DataSnapshot作业=userSnapshot.child(作业ID);
//在这里您可以使用作业快照
bid_count.addAndGet(1);//类似的东西?
}
}
}
}
});
基本上,您是将侦听器添加到非嵌套或深度的对象,并使用循环获取子对象,而不是将侦听器添加到嵌套的子对象


希望这能有所帮助。

请添加您的数据库结构并指明您想要获取的确切数据。您获取整个jobs数据库不是为了一个用户查询吗?听起来很贵,不是吗?我不认为很贵。Firebase是一个基于NoSQL的实时数据库。它功能强大,足以处理您正在尝试的操作。您不能不要编写查询并提取数据库的一部分。如果需要,可以尝试重新构造数据库。如果我错了,请更正我的错误,但行mDatabaseUser.addListenerForSingleValueEvent将将整个作业数据库提取到客户端电话,无论firebase的性能如何efficient@DsCpp是的,这会把所有的数据都放在本地,我不认为是expensive。如果“作业”中的数据太多,您可以通过添加
.limitToFirst(1000)
.limitToLast(500)