Android Firebase等待数据

时间:2016-09-13 19:43:45

标签: android firebase firebase-realtime-database wait

在我的Android应用程序中,我创建了一个包含ListView的活动,该活动填充了Firebase数据库中的数据。

数据库结构的JSON树如下:

{
  "companies" : {
    "companyX" : {
      "address" : "50th avenue, NY",
      "name" : "Spare-Tools Ltd."
    },
    "companyZ" : {
      "address" : "50th Broadway, NY",
      "name" : "Burgers and Burgers"
    }
  },
  "company-requests" : {
    "companyX" : {
      "req1" : true
      "req2" : true
    }
  },
  "requests" : {
    "req1" : {
      "destination" : "Upper Tooting 122, Bronx",
      "origin" : "Philadelphia",
      "time" : "1473593287",
      ...
    }
    "req2" : {
      ...
    }
  }
}

我想使用ListView节点的请求列表填充requests。但我首先需要知道属于特定公司的所有请求,因此我首先转到company-requests节点并检索属于特定公司的所有请求密钥。 我面临的问题是在数据库的最终数据到达之前创建了ListView

public class RequestsListActivity extends AppCompatActivity {
    private ListView rListView;
    DatabaseReference rootNode = FirebaseDatabase.getInstance().getReference();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        rListView = (ListView) findViewById(R.id.result_list_view);
        //First I retrieve all the requests of a specific company
        DatabaseReference companyRequests = rootNode.child("company-requests/companyX");

        companyRequests.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //Then I retrieve all the keys of these requests
                ...
                while (iterator.hasNext()) {
                    String key = iterator.next().getKey();
                    //For each key I retrieve its details from the requests node
                    DatabaseReference currRequest = rootNode.child("requests/" + key);
                    currRequest.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            String time;
                            time = (String) dataSnapshot.child("time").getValue();
                            Request request = new Request(time);
                            allRequests.add(request);
                        }
                        ...onCancelled...
                    });
                }
                //THIS CODE IS EXECUTED TO EARLY: BEFORE WE HAVE ANY DATA FROM FIREBASE
                RequestAdapter adapter = new RequestAdapter(RequestsListActivity.this, allRequests);
                rListView.setAdapter(adapter);

                }

            ...onCancelled...
        });
    }
}

如何插入等待从Firebase加载值的wait(微调器?)?

2 个答案:

答案 0 :(得分:5)

您可以使用简单的计数器来跟踪待处理负载的数量:

RewriteRule ^example/$ http://www.mainsite.com/example.html [R=301,L]

RewriteCond %{HTTP_HOST} ^.*forwardeddomain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/example/ [NC]
RewriteRule ^ http://www.mainsite.com [R=301,L]

答案 1 :(得分:0)

我使用java.util.concurrent.CountDownLatch

解决了这个问题

在此示例中,将EquityTotalListener替换为ValueEventListener的实现。

private void recalculate() {
        final AtomicLong sumUpAll = new AtomicLong();
        final CountDownLatch cnt = new CountDownLatch(mapUid2GeoLocation.keySet().size());
        for (final String uid : mapUid2GeoLocation.keySet()) {
            EquityTotalListener el = mapUid2EquityListener.get(uid);
            if (el != null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Listener for " + uid + " already set up");
                    cnt.countDown();
                }
            } else {
                el = new EquityTotalListener(database.getDatabase(), uid) {

                    @Override
                    public void onCancelled(final DatabaseError databaseError) {
                        super.onCancelled(databaseError);
                        cnt.countDown();
                    }

                    @Override
                    protected void valueChanged(final String key, final Object value) {
                        if (value != null) {
                            sumUpAll.getAndAdd(Long.parseLong(value.toString()));
                            cnt.countDown();
                        }
                    };
                }.attach();
                mapUid2EquityListener.put(uid, el);
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Waitung for countdown..");
        }
        try {
            final boolean allGood = cnt.await(10, TimeUnit.SECONDS);
            if (allGood) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Done waiting, " + uid + " owns " + sumUpAll.get() + " equity");
                }
            } else {
                if (logger.isWarnEnabled()) {
                    logger.warn("Waiting for read operations ran into timeout");
                }
            }
        } catch (final InterruptedException e) {
            if (logger.isErrorEnabled()) {
                logger.error(e.getLocalizedMessage(), e);
            }
        }

    }