I have a list of string and this list contains node names in Firebase database.
And I have a custom sort method therefore I want to get the all of the keys for each node in my custom list without using Firebase` query sorting functions. And because of it I need all data to be retrieved, so adding to list as it retrieves some data is not an option.
However the problem starts with asynchronous structure of Firebase.
I iterate through every node name in my custom list and under that loop I create another loop in Firebase` thread ( addListenerForSingleValueEvent ) to retrieve all keys. But it works asynchronously. I've tried to change it to synchronous by using Thread and Semaphore but it didn't work. I've also used custom interface (FirebaseDataRetrieveListener) to indicate when the loop in valueEventListener finishes but since valueEventListener instantly return this is not possible without pausing the thread.
If Task's can be used in this situation, how it could be, or are there any other solutions?
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);
}