I've been having trouble retrieving array contents from a firebase document using a method. Upon testing, the array initially prints [], but as the code goes on it prints the correct values? I don't know if my approach is correct so any suggestions will be appreciated.
Future method
Future<List<dynamic>> retrieveMovieList(String uid) async{
List<dynamic> movies = [];
final docRef = await _firestore.collection('users').doc(uid);
docRef.get().then(
(DocumentSnapshot doc) async{
final data = doc.data() as Map<String, dynamic>;
movies = await data['movies'];
// If i print movies here it works. (await is an experiment, it also doesnt work without it)
},
one rror: (e) => print("Error getting document: $e"),
);
return movies;
}
Method being called
List<dynamic> list = await data.retrieveMovieList(uid);
List<Widget> movies = await load.getMoviesById(list);
When the list is being printed all I get is [] initially. Any help, or can anyone point out what I'm doing wrong?
CodePudding user response:
The problem is that your code reaches return movies;
before movies = await data['movies'];
happens, and the reason is that the code inside your callback runs asynchronously and you are not awaiting it.
What you need to do is
Future<List<dynamic>> retrieveMovieList(String uid) async{
try {
List<dynamic> movies = [];
final docRef = await _firestore.collection('users').doc(uid);
final doc = await docRef.get(); // here we need to await
final data = doc.data() as Map<String, dynamic>;
movies = data['movies']; // you had await movies but I don't think you need await
return movies;
} catch (e) {
print("Error getting document: $e")
}
}
CodePudding user response:
the return movies;
will be executed immediately since it's outside the then
, it will wait for what's inside it code block, but runs other code in parallel, instead use a full method with await/async:
Future<List<dynamic>> retrieveMovieList(String uid) async{
List<dynamic> movies = [];
final docRef = await _firestore.collection('users').doc(uid);
final docSnap = await docRef.get();
final data = docSnap.data() as Map<String, dynamic>;
movies = data['movies'] as List;
},
one rror: (e) => print("Error getting document: $e"),
);
return movies;
}
or you can simply include the return movies;
inside the then
code block