在我的应用程序中,我可以通过datasnapshot.getchildren()来计算子项数。 但是,如果我想将该计数存储在变量中,我该怎么办?
mRefReg.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(dataSnapshot.getKey(),dataSnapshot.getChildrenCount()+"Count");
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
包括“mCount = dataSnapshot.getChildren”似乎不起作用。
答案 0 :(得分:4)
您可能会看到来自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);
因为输出将是:
在添加listener之前: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中的计数就会更新。
答案 1 :(得分:2)
您的问题中缺少一些信息,但我想我知道发生了什么。 Firebase中的监听器是异步的,因此您无法轻松设置变量。
要去的选项:
1)在onDataChange方法中声明你的变量。
2)仅在onDataChange方法完成时使用变量。
3)在您声明了监听器的方法中传递回调函数。
答案 2 :(得分:0)
long ct = 0;
public void Count() {
databaseReference.child("a").child("b").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
ct = dataSnapshot.getChildrenCount()`enter code here`;
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
在开头调用此函数,每当firebase数据库中的子计数增加或减少时,它将不断更新变量ct。 希望它有所帮助
答案 3 :(得分:0)
只需执行此操作。函数datasnapshot.getChildrenCount
返回long类型值,因此您需要先将其强制转换为整数。
mRefReg.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
mCount = (int) dataSnapshot.getChildrenCount;
Log.i(dataSnapshot.getKey(), mCount +""`enter code here`);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});