您看到的可能是 Firebase 中的数据是异步加载的。当你第一次遇到这种情况时,这是一个巨大的范式转变。但由于大多数现代云 API 都以这种方式工作,因此最好尽快接受它。
我发现的最简单的方法是查看当我们放置一些日志语句时会发生什么:
System.out.println("Before adding listener");
mRefReg.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("In onDataChange");
}
public void onCancelled(DatabaseError databaseError) { }
});
System.out.println("After adding listener");
与你的直觉告诉你的相反,它的输出将是:
添加监听器之前
添加监听器后
在 onDataChange 中
原因是(正如我在开始时所说)Firebase 异步从数据库中获取数据。一种有趣的方式来了解为什么会这样,是对您的数据进行更改(例如在您的Firebase Database console 中)。当您进行此更改时,onDataChange 将再次被调用并打印另一个:
在 onDataChange 中
很遗憾,这意味着您无法执行以下操作来处理孩子数:
int count = -1;
System.out.println("Before adding listener, count="+count);
mRefReg.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
count = dataSnapshot.getChildrenCount();
System.out.println("In onDataChange, count="+count);
}
public void onCancelled(DatabaseError databaseError) { }
});
System.out.println("After adding listener, count="+count);
因为输出将是:
添加监听器之前:count=-1
添加监听器后:count=-1
在 onDataChange 中:count=3(假设您有 3 个孩子)
我发现处理这种异步加载的最佳技巧是重新构建问题。不要说“首先我们得到计数,然后我们用它做 xyz”,而是尝试将其构建为“每当我们得到计数时,就用它做 xyz”。这意味着你需要将需要计数的代码移动到到 onDataChange():
mRefReg.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
int count = dataSnapshot.getChildrenCount();
// TODO: show the count in the UI
}
public void onCancelled(DatabaseError databaseError) { }
});
如果你像这样实现它,UI中的计数将在数据库中的项目数发生变化时更新。