我正在我的应用中实现firebase。请参考下面的图片作为我的数据库的参考。
我有一个SLC名称数组,我需要生成一个SLC键的arrayList。所以我试图创建一个特定SLC密钥的arrayList。请参阅以下代码一次。
for (int i = 0; i < arr.size(); i++)
{
Query query = ref.child(pref.getString("groupSelectedDCU", "") + "/" + "DeviceList")
.orderByChild("name")
.equalTo(arr.get(i));
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child: dataSnapshot.getChildren())
{
Log.d("arrID", child.getKey() + "");
arrID.add(child.getKey());
}
Log.d("arrID", Arrays.toString(arrID.toArray()));
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
Log.d("arrID", Arrays.toString(arrID.toArray()));
这里我试图将所有SLC密钥添加到arrID
arraylist中。但是在访问arrayList时,它返回一个空数组。我错过了什么或者我是否需要添加更多听众?需要你的帮助。
答案 0 :(得分:2)
你误解了addListenerForSingleValueEvent
是如何运作的。当查询响应最终从网络到达时,提供的ValueEventListener
方法将在后台异步调用 。因此,当最后一个语句运行时(在 for循环之后):
...
Log.d("arrID", Arrays.toString(arrID.toArray()));
arrID
仍然为空,因为尚未调用任何onDataChange
方法。
替代解决方案。如果您需要等到所有查询完成,请尝试以下方法:
List<String> arrID = ArrayList<String>();
int remainingQueries = arr.size();
for (int i = 0; i < arr.size(); i++) {
Query query = ...
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child: dataSnapshot.getChildren()) {
Log.d("arrID", child.getKey() + "");
arrID.add(child.getKey());
}
Log.d("arrID", Arrays.toString(arrID.toArray()));
if (--remainingQueries == 0) onQueriesDone(arrID);
}
@Override
public void onCancelled(FirebaseError firebaseError) { }
});
}
完成后会调用此方法:
private void onQueriesDone(List<String> arrID) {
Log.d("arrID", Arrays.toString(arrID.toArray()));
}
特别是,我们不需要同步锁来访问共享计数器remainingQueries
,因为所有Firebase回调都是在主线程上触发的。