首页 > 解决方案 > 有没有什么办法只有在我从 Android 中的 Firebase 获取数据后才能继续?

问题描述

我正在为一家酒店开发一款应用程序,该应用程序使酒店管理人员能够报告和查看疑虑和问题。我正在为这个应用程序使用 Android 和 Firebase。

以下是报告关注的数据库结构: 关注POJO结构

为了最大限度地减少数据下载和优化速度,我在数据库中添加了“活动”和“已解决”节点,如下所示:

在此处输入图像描述

现在,酒店希望我添加创建 Excel 报告的功能,报告过去一个月内关闭/解决的问题。为此,我将在“已解决”节点上附加一个单值事件侦听器,获取已解决问题的键,然后对于每个键,从“allConcerns”节点获取数据,将每个节点的数据存储到字符串的 ArrayList 中。之后,我将使用此 JSON to Excel API for Android创建 Excel 文件。

我可以使用以下代码访问已解决问题的密钥:

DatabaseReference resolvedReference = FirebaseDatabase.getInstance().getReference()
            .child(getApplicationContext().getResources().getString(R.string.concerns))
            .child(getApplicationContext().getResources().getString(R.string.resolved));

    final ArrayList<String> keys = new ArrayList<>();

    resolvedReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {

            //Getting keys of all resolved concerns in keys arraylist here
            for (DataSnapshot ds : snapshot.getChildren()){
                keys.add(ds.getValue(String.class));
            }

            //Storing JSON data in this arraylist
            final ArrayList<String> data = new ArrayList<>();

            for(int i = 0; i<keys.size() ; ++i){
                String key = keys.get(i);

            //Getting data of each concern here  
            FirebaseDatabase.getInstance().getReference().child(getApplicationContext().getResources().getString(R.string.allConcerns))
                        .child(key).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        String type = snapshot.child("type").getValue().toString();
                        Log.i("Type", type);
                        if(type.equals("0")) {
                            SafetyConcernClass s = snapshot.getValue(SafetyConcernClass.class);
                            Log.i("Snapshot of key", s.toString());
                            data.add(s.toString());
                        }
                        else{
                            GembaWalkClass g = snapshot.getValue(GembaWalkClass.class);
                            Log.i("Snapshot of key", g.toString());
                            data.add(g.toString());
                        }
                        Proof proof = snapshot.child("proof").getValue(Proof.class);
                        Log.i("Proof", proof.toString());
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });
            }

            //Issue I am facing is here
            Log.i("Data size", String.valueOf(data.size()));

        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

}

这里真正的问题是在记录 data.size() 时。由于 Firebase 是异步的,FOR 循环在获取数据并将其输入数据 ArrayList 之前结束,因此它给我的大小为 0。由于没有获取数据,我无法创建 Excel 文件。

我的问题是,如何确保仅在将相应已解决问题的数据存储在 ArrayList 中之后才继续记录 data.size()?

标签: javaandroidfirebasefirebase-realtime-database

解决方案


典型的方法是保留一个计数器或倒计时锁来跟踪您已经下载了多少关注快照。一旦柜台到达keys.size()你就知道你已经完成了。

另请参阅在 Firebase 侦听器中设置 Singleton 属性值


推荐阅读