【发布时间】:2018-10-13 15:50:55
【问题描述】:
我有一个字符串列表,该列表包含 Firebase 数据库中的节点名称。
而且我有一个自定义排序方法,因此我想在不使用 Firebase 查询排序函数的情况下获取自定义列表中每个节点的所有键。 正因为如此,我需要检索所有数据,因此在检索某些数据时添加到列表不是一种选择。
但是问题始于 Firebase 的异步结构。
我遍历自定义列表中的每个节点名称,并在该循环下在 Firebase 线程 ( addListenerForSingleValueEvent ) 中创建另一个循环以检索所有键。 但它是异步工作的。我试图通过使用 Thread 和 Semaphore 将其更改为同步,但它没有用。 我还使用自定义接口 (FirebaseDataRetrieveListener) 来指示 valueEventListener 中的循环何时完成,但由于 valueEventListener 立即返回,因此如果不暂停线程,这是不可能的。
如果在这种情况下可以使用Task,那该怎么做,或者有其他解决方案吗?
private void getKeysFromNodeList(final FirebaseDataRetrieveListener listener) //TODO [BUG] when first for loop initializes it ignores the seperate thread in the inner anonymous class so it'll be already finished it's cycle before Firebase` loop starts...
{
listener.onStart();
final DatabaseReference databaseRef = firebaseInstance.rootRef.child(context.getString(R.string.databaseref));
for (iterator = 0; iterator < nodeList.size(); iterator ++)
{
Query query = databaseRed.child(nodeList.get(iterator));
query.addListenerForSingleValueEvent(new ValueEventListener()
{
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{
for (DataSnapshot snap : dataSnapshot.getChildren())
{
iterator++;
String key= snap.getKey();
// I've done my jobs with given key here
// if got the last key from node and iterated the last node
if (firebaseIterator== dataSnapshot.getChildrenCount() - 1 && iterator == nodeList.size() - 1)
{
firebaseIterator= 0;// reset the iterators
iterator= 0;
listener.onSuccess();
break;
}
// if got the last key from node
else if (firebaseIterator== dataSnapshot.getChildrenCount() - 1)
{
firebaseIterator= 0; // reset the iterator
break;
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
listener.onFailed(databaseError);
return;
}
});
}
;
}
}
FirebaseDataRetrieveListener.java
public interface FirebaseDataRetrieveListener
{
public void onStart();
public void onSuccess();
public void onFailed(DatabaseError databaseError);
}
【问题讨论】:
标签: android firebase asynchronous firebase-realtime-database