我正在尝试编写一个返回映射的方法,该方法应包含firebase中所有节点的孩子,但是由于我必须使用回调,方法返回一个空的地图。
public Map<Date, String> getChildrenAsMap(String nodeId) {
DatabaseReference refernce= dbRoot.child("childName").child(nodeId);
final Map<Date, String> childMap = new HashMap<>();
refernce.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<Date, String> data = (Map<Date, String>) dataSnapshot.getValue();
for (Map.Entry<Date, String> entry : data.entrySet()) {
childMap .put(entry.getKey(), (String) entry.getValue());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
return childMap;
}
发生这种情况是因为firebase查询发生异步,并且在返回地图后被召唤。保持简单:您无法做出这样的异步方法,因为ValueEventListener
已经是一个完全执行此操作的接口。如果您想要这样的方法来工作,则需要创建一个为您处理它的类,但这是无需的,因为您拥有 firebase提供的一切,firbase for Android :
DatabaseReference refernce= dbRoot.child("childName").child(nodeId);
deviceHistory.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<Date, String> childMap = new HashMap<>();
Map<Date, String> data = (Map<Date, String>) dataSnapshot.getValue();
for (Map.Entry<Date, String> entry : data.entrySet()) {
childMap.put(entry.getKey(), (String) entry.getValue());
}
// handle your childMap modifications in here, this gets executed after the value is retrieved
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
我写了另一个类似的注释(尽管对于Swift,但这不是相关点)。每次您要使用它时,您只需要将逻辑写入ValueEventListener
即可。它已经是一种方法,因此您不需要创建一个新的方法。