Firebase Android OnDataChange不会打电话



我要做的是从firebase获取用户ID列表,然后从每个用户中获取数据。我遇到的问题是,虽然我可以很高兴地检索ID列表,但它似乎行不通 - 此查询的onDataChange从未达到。

我尝试通过删除for循环甚至为ID进行硬编码来修改configurePage中的代码,但是无论我做什么,都不会添加到listOfItems中,并且您仍然无法达到onDataChangeconfigurePage中的日志行显示了正确的ID数,因此我可以排除第一个查询,而不是及时完成第二次。

第一个查询:

public void getIDs() {
    spinner.setVisibility(View.VISIBLE);
    search = mDatabase.child("linked_users").child(userID);
    val = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "Test:" + dataSnapshot.getChildrenCount());
            for (DataSnapshot singleChild : dataSnapshot.getChildren()) {
                listOfIDs.add(singleChild.getKey());
            }
            if (listOfIDs.size() == 0) {
                spinner.setVisibility(View.GONE);
                noResultsLabel.setVisibility(View.VISIBLE);
                countLabel.setVisibility(View.GONE);
            } else {
                countLabel.setText("Total users: " + listOfIDs.size());
                countLabel.setVisibility(View.VISIBLE);
                configurePage();
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.d(TAG, "DB problem");
            AlertDialog.Builder dialog = new AlertDialog.Builder(AgentViewUsers.this);
            dialog = databaseDialog(dialog);
            dialog.show();
        }
    };
    search.addListenerForSingleValueEvent(val);
}

第二查询:

public void configurePage() {
    Log.d(TAG, "test = " + listOfIDs.size());
    for (String id : listOfIDs){
        mDatabase.child("users").child(id).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                AgentUserViewObject obj = new AgentUserViewObject();
                obj.name = dataSnapshot.child("full_name").getValue().toString();
                obj.address = dataSnapshot.child("address").getValue().toString() + ", " + dataSnapshot.child("towncounty").getValue().toString() + ", " + dataSnapshot.child("postcode").getValue().toString();
                obj.requestCount = Integer.parseInt(dataSnapshot.child("requests_submitted").getValue().toString());
                listOfItems.add(obj);
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
    }
    mLayoutManager = new LinearLayoutManager(AgentViewUsers.this);
    mAdapter = new AgentUserViewAdapter(listOfItems);
    mRecyclerView.addItemDecoration(new DividerItemDecoration(AgentViewUsers.this,DividerItemDecoration.VERTICAL_LIST));
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);
    spinner.setVisibility(View.GONE);
}

您看到的是预期的行为。Firebase(与大多数现代云API一样)加载并从服务器异步更新数据。因此,当您调用addListenerForSingleValueEvent时, 同步数据。但是直到(可能稍后)才能完成。

因此,在处理Firebase时,您应该以不同的方式思考。而不是编码"首先获取数据,然后使用该数据更新列表视图",而是将代码重新构架为"每当我们获取数据时,我们都会使用该数据更新列表视图"。

在此改选方法中,您需要从onDataChange()方法中更新列表视图。为此,您可以致电adapter.notifyDataSetChanged()

Log.d(TAG, "test = " + listOfIDs.size());
for (String id : listOfIDs){
    mDatabase.child("users").child(id).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            AgentUserViewObject obj = new AgentUserViewObject();
            obj.name = dataSnapshot.child("full_name").getValue().toString();
            obj.address = dataSnapshot.child("address").getValue().toString() + ", " + dataSnapshot.child("towncounty").getValue().toString() + ", " + dataSnapshot.child("postcode").getValue().toString();
            obj.requestCount = Integer.parseInt(dataSnapshot.child("requests_submitted").getValue().toString());
            listOfItems.add(obj);
            mAdapter.notifyDataSetChanged(); // tell the adapter to redraw the view
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}
mLayoutManager = new LinearLayoutManager(AgentViewUsers.this);
mAdapter = new AgentUserViewAdapter(listOfItems);
mRecyclerView.addItemDecoration(new DividerItemDecoration(AgentViewUsers.this,DividerItemDecoration.VERTICAL_LIST));
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
spinner.setVisibility(View.GONE);

最新更新