Welcome to 16892 Developer Community-Open, Learning,Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm developing a flutter app and using firestore as backend: my DB structure is:

  • User (Collection)
    • userid (User property)
    • Books (SubCollection)
      • booksList (array of Objects(or map as firestore calls them))

The function to retrieve each book from booksList array is:

Future<List<Book>> bookshelf(String userId) async {
  return await FirebaseFirestore.instance
      .collection('Users')
      .where('userId', isEqualTo: userId)
      .get()
      .then((querySnapshot) => querySnapshot.docs.map((doc) => doc.reference
          .collection('Books')
          .get()
          .then((querySnapshot) => querySnapshot.docs.forEach((doc) {
                var books = doc.data()['bookList'];
                return books
                    .map<Book>((elem) => Book(title: elem['title']));
              }))).toList());

My problem is that I'm not able to return Future<List<Book>>;
I've tried to create an array and add elements to it at line 12 (where I'm actually getting the books correctly) but it didn't work since the return statement wasn't waiting for the query to complete.
Basically I'm not able to transform the object I get into a Future<List> as I need for the function. Right now I'm getting a "MappedListIterable<QueryDocumentSnapshot, Future>".
Thanks.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
650 views
Welcome To Ask or Share your Answers For Others

1 Answer

The error is caused by the forEach method inside the most nested Promise callback, because the forEach method always returns void, however a Book is expected. There will also be an error caused by the nested lists, which can be resolved by flattening the nested lists using the expand method. I have modified your code sample to remove the forEach method and reduce the Promise callback nesting:

Future<List<Book>> bookshelf(String userId) async {
  return await FirebaseFirestore.instance
      .collection('Users')
      .where('userId', isEqualTo: userId)
      .get()
      // Maps each user query snapshot to a list of book query snapshots.
      .then(
        (snapshot) => Future.wait(
          snapshot.docs.map((doc) => doc.reference.collection('Books').get()),
        ),
      )
      // Maps each list of book query snapshots to a list of book document snapshots.
      .then(
        (snapshots) => snapshots.expand((snapshot) => snapshot.docs),
      )
      // Maps each list of book document snapshots to a list of raw books.
      .then(
        (docs) => docs.expand((doc) => doc.data()['bookList'] as List),
      )
      // Maps each list of raw books to a list of books.
      .then(
        (books) => books.map((book) => Book(title: book['title'])).toList(),
      );
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to 16892 Developer Community-Open, Learning and Share
...