Tomas Ward
Tomas Ward

Reputation: 1164

Wait for query inside for loop - Flutter Firebase

I have this function that creates a list of users from their ids. A query is made for each id to get the information from Firebase RTDB.

static List<FrediUser> formattedParticipantListFromIDs(List<String> participantIDs) {
List<FrediUser> formattedParticipants = [];

for (String id in participantIDs) {
  dbQuery(2, 'users', id).once().then((value) {
    formattedParticipants.add(FrediUser.fromMap(value.snapshot.value as Map));
  });
}

print(formattedParticipants.length);
Future.delayed(const Duration(seconds: 3), () {
  print(formattedParticipants.length);
});

return formattedParticipants;  }

Output of 1st print statement

0

Output of 2nd print statement

3


The Problem

The return is always an empty list. As you can see, the loop and the return statement do not wait for the list to be populated. BUT, if you wait 3 seconds, the list did get populated, but it is too late.

How can I wait, in each iteration of the for loop, for the query to be done AND the .then to be called and completed?

*This method is called in a factory constructor function of a class, therefore futures and awaits cannot be used.

Upvotes: 0

Views: 338

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599031

You'll want to use await to wait for the asynchronous once() method.

//      👇
static Future<List<FrediUser>> formattedParticipantListFromIDs(List<String> participantIDs) 
async {
// 👆   
  List<FrediUser> formattedParticipants = [];

  for (String id in participantIDs) {
              // 👇
    var value = await dbQuery(2, 'users', id).once();
    formattedParticipants.add(FrediUser.fromMap(value.snapshot.value as Map));
  }

  print(formattedParticipants.length);

  return formattedParticipants;  
}

As you'll see, this means that your formattedParticipantListFromIDs function has to be marked as async, and returns a Future. There is no way to prevent this, as there's no way to make asynchronous code behave synchronously.

For more on this, I recommend taking the Dart codelab on Asynchronous programming: futures, async, await

Upvotes: 1

Related Questions