Reputation: 153
I'm using the following FutureBuilder to handle fetching 'squad' info from a Firebase database, but the Future is saying it's done before I can process all the data form the database:
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _getUserSquads(),
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
if (_userSquads == null) {...} else {
print(snapshot.connectionState);
return Text(_userSquads.length.toString());
}
}
},
);
... the following two functions are the functions I need to be completed before the FutureBuilder is done:
Future<void> _getUserSquads() async {
print('1');
final squadIdsResult = await _userSquadsRef.once();
print('2');
if (squadIdsResult.value == null) {
print('3');
return;
}
print('4');
_userSquadIds = squadIdsResult.value;
print('5');
final test = await _test();
print('6');
}
Future<void> _test() {
print('7');
_userSquadIds.forEach((key, value) async {
print('itter');
final result = await _squadsRef.child(key).once();
_userSquads.add(result.value);
print(result.value);
print(_userSquads);
});
print('8');
print('9');
}
The two print statements print(result.value)
and print(_useraSquads)
don't execute until after the Future's connection state is done:
I/flutter (29217): 2
I/flutter (29217): 4
I/flutter (29217): 5
I/flutter (29217): 7
I/flutter (29217): itter
I/flutter (29217): 8
I/flutter (29217): 9
I/flutter (29217): 6
I/flutter (29217): ConnectionState.done
I/flutter (29217): {squadName: SAFTS}
I/flutter (29217): [{squadName: SAFTS}]
It seems like the problem is in the _test()
function, but I've tried a hundred different ways to write this, and I can't figure out how to make sure that the code is done fetching the data from the database in the forEach
block before the Future is set to done.
Upvotes: 0
Views: 465
Reputation: 27147
Your _userSquadIds's foreach is creating issue. If you want to make it async the you can use Future.forEach.
Change following code.
_userSquadIds.forEach((key, value) async {
print('itter');
final result = await _squadsRef.child(key).once();
_userSquads.add(result.value);
print(result.value);
print(_userSquads);
});
With Following one.
await Future.forEach(_userSquadIds, (key,value) async {
print('itter');
final result = await _squadsRef.child(key).once();
_userSquads.add(result.value);
print(result.value);
print(_userSquads);
});
Upvotes: 1