2017-06-01 113 views
0

我正在我的应用中实施Firebase。请参考下面的图片作为我的数据库的参考。ArrayList在从Firebase数据库获取数据后显示为空

The SLC Structure

我SLC名称的数组,我需要生成SLC键的ArrayList。所以我想创建一个特定的SLC键的数组列表。请参阅下面的代码一次。

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时,它返回一个空数组。我是否错过了一些东西,或者是否必须添加更多的听众?需要你的帮助。

+0

不是基于Json的firebase吗? – Zoe

+0

@LunarWatcher:是的,它是 –

+0

你解析它正确吗? – Zoe

回答

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回调。

相关问题