我要做的是从firebase获取用户ID列表,然后从每个用户中获取数据。我遇到的问题是,虽然我可以很高兴地检索ID列表,但它似乎行不通 - 此查询的onDataChange
从未达到。
我尝试通过删除for循环甚至为ID进行硬编码来修改configurePage
中的代码,但是无论我做什么,都不会添加到listOfItems
中,并且您仍然无法达到onDataChange
。configurePage
中的日志行显示了正确的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);