skip to Main Content

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)
      },
      onError: (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?

2

Answers


  1. 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")
        }
      }
    
    Login or Signup to reply.
  2. 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;
          },
          onError: (e) => print("Error getting document: $e"),
        );
        return movies;
      }
    

    or you can simply include the return movies; inside the then code block

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search