TM Lynch
TM Lynch

Reputation: 504

How can I retrieve 3 collections from Firestore in a FutureBuilder? Using Future.wait but getting errors

I need to pull three lists from Firestore before building my UI. Using a Future.wait I am getting an error. Here is my code:

Here is the declaration of the variables for the futures:

  // Variables for the futures
  Future<List<FilingData>>? filingList;
  Future<List<ClientData>>? clientList;
  Future<List<UserData>>? userList;

  // Variables for the retrieved data 
  List<FilingData>? retrievedFilingList;
  List<ClientData>? retrievedClientList;
  List<UserData>? retrievedUserList;

Here is the function that pulls the first list (the other two are just like it):

Future<List<FilingData>> retrieveFilings() async {
    QuerySnapshot<Map<String, dynamic>> snapshot =
        await _db.collection('filings').get();
    return snapshot.docs
        .map((docSnapshot) => FilingData.fromDocumentSnapshot(docSnapshot))
        .toList();
  }

Here is the initialization of the futures:

@override
  void initState() {
    super.initState();
    _initRetrieval(); // obtain the futures here.  Must be done here to avoid creating every build.
  }

  // Set up the futures for the FutureBuilder and the data lists upon retrieval.
  Future<void> _initRetrieval() async {
    filingList = filingService.retrieveFilings();
    retrievedFilingList = await filingService.retrieveFilings();

    clientList = clientService.retrieveClients();
    retrievedClientList = await clientService.retrieveClients();
    
    userList = userService.retrieveUsers();
    retrievedUserList = await userService.retrieveUsers();
  }

Here is the FutureBuilder:

  @override
  Widget build(BuildContext context) {
    
    return FutureBuilder(
      future:   Future.wait([filingList, clientList, userList]),
      builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
        if (snapshot.hasData && snapshot.data!.isNotEmpty) {
     
        return Material( <Build UI> ...

And here is the lint error which is on [filingList, clientList, userList] in the Future.wait:

Couldn't infer type parameter 'E'.
    
Tried to infer 'Future<List<Object>>?' for 'E' which doesn't work:   

Return type declared as 'List<E>'used where  'Iterable<Future<_>>' is required. 

The type 'Future<List<Object>>?' was inferred from:   
Parameter 'element' declared as 'E' but argument is 'Future<List<FilingData>>?'.   
Parameter 'element' declared as 'E' but argument is 'Future<List<ClientData>>?'.   
Parameter 'element' declared as 'E' but argument is 'Future<List<UserData>>?'.

So I added <List<dynamic>> to the Future.wait like this:

future:   Future.wait<List<dynamic>>([filingList, clientList, userList])

and now I'm getting other type errors:

The element type 'Future<List<FilingData>>?' can't be assigned to the list type 'Future<List<dynamic>>'.

This seems like a common problem, which I tried to fix with late Future<List<FilingData>> filingList; in the declarations. But it crashes on the late as not initialized.

Upvotes: 1

Views: 45

Answers (0)

Related Questions