Reputation: 15
We have 2 documents in a Collection "Modules", which in turn have 5 and 6 documents respectively, in a collection called "Lessons" under "Modules". When we run a loop to parse the documents in collection "Modules" to get the documents from collection "Lessons" using Firestore, the outer for loop runs faster than the firestore query itself, causing the values to get interchanged between the collections. We tried finding multiple solutions to this, using Tasks.whenAllSuccess() or Tasks.whenAllComplete(), but nothing worked other than putting the main thread to sleep for 1 second. In this case, the queries fetched the appropriate values. However, putting the thread to sleep will definitely freeze the app, which is undesirable. Attached below are code snippets:
for (String moduleId : modulesDocumentIds)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
firebaseFirestore.collection("Users")
.document(userDocumentId)
.collection("Courses")
.document(courseDocumentId)
.collection("Modules")
.document(moduleId)
.collection("Lessons")
.orderBy("lesson_number",Query.Direction.ASCENDING)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
for (QueryDocumentSnapshot queryDocumentSnapshot : task.getResult())
{
// Showing Lessons
updateCourseCompletion();
}
});
}
}
}
}
}
});
Here, if moduleDocumentIds has 2 String values, without putting the Thread to sleep, since the for loop runs faster than the Firestore Query task, the lessons are fetched for the second moduleId string, and then the lessons are fetched for the first moduleId String, causing a swap of values. We are not able to find a solution for this yet. Could anyone please advice on this?
Upvotes: 1
Views: 196
Reputation: 795
You can create a function for firestore query and call that function once you received response for an item of for loop.
private fun firebasecall() {
var module = modulesDocumentIds.get(index)
//place your firestore call here
firebaseFirestore.collection("Users")
.document(userDocumentId)
.collection("Courses")
.document(courseDocumentId)
.collection("Modules")
.document(moduleId)
.collection("Lessons")
.orderBy("lesson_number",Query.Direction.ASCENDING)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull (Task<QuerySnapshot>) task) {
index++
if (index < modulesDocumentIds.size) {
firebasecall()
} else {
//loop completes
}
});
}
}
Call method first time:
if (modulesDocumentIds.size > 0) {
firebasecall()
}
Hope it will helps.
Upvotes: 5