如何在从Firebase读取数据时使用嵌套for循环(使用Java)?

时间:2018-03-04 17:49:39

标签: java android firebase firebase-realtime-database

我正在将Firebase用于我的Android应用程序的数据库。我需要查看数据库中所有人的三元组并为每个组分配一个分数,这样我才能找到得分最高的组。所以我想到的就像这个伪代码:

for person1 in People {
    for person2 in People{
        for person3 in People{
            if(calculateScore(person1, person2, person3)>score){
                score = calculateScore(person1, person2, person3);
            }
        }
    }
}

所以我的代码是这样的:

peopleRef.addListenerForSingleValueEvent(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {


        for (DataSnapshot childDataSnapshot1 : dataSnapshot.getChildren()) {

            Log.d("TAG", "1st loop");

            peopleRef.addListenerForSingleValueEvent(new ValueEventListener() {

                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {


                    for (DataSnapshot childDataSnapshot2 : dataSnapshot.getChildren()) {

                        Log.d("TAG", "2nd loop");

                        peopleRef.addListenerForSingleValueEvent(new ValueEventListener() {

                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {


                                for (DataSnapshot childDataSnapshot3 : dataSnapshot.getChildren()) {

                                    Log.d("TAG", "3rd loop");

                                    int score = calculateScore(childDataSnapshot1, childDataSnapshot2, childDataSnapshot3);
                                    if(score > bestScore){
                                        bestScore = score;
                                    }

                                }

                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        }

                    }

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            }

        }

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
}

问题是,执行的顺序混乱了。我希望它像1 2 333333333 2 333333333 2 33333333 1 2 33333333 2 333333 ...但它打印的东西像1111 2222222222222 33333333 ...

我知道Firebase是异步的,但我认为它应该可以工作,因为我以嵌套方式调用onDataChange中的所有内容。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

ValueEventListener()返回任何数据库引用节点下的所有数据。因此,以递归方式在同一节点上调用同一个侦听器是没用的。

加载完所有数据后,您可以使用for循环存储所有对象并将其与内存进行比较。

for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
    // parse person snapshot
    // add to list
}

// then compare with for loop
// int score = calculateScore(person1, person2, person3);

答案 1 :(得分:0)

从Firebase数据库获取数据时使用嵌套循环并不能保证您获得循环顺序的结果。发生这种情况是因为循环中的每个onDataChange()方法都有其异步行为,因此嵌套那些循环并不能解决执行顺序。

不幸的是,您无法知道何时从数据库中获取数据以便调用第二个循环。这是因为Firebase是一个实时数据库,并且获取数据可能永远不会完成。这就是为什么命名为实时数据库,因为在任何momemnt中都可以更改数据库,可以添加或删除项目。