Search code examples
firebasefluttergoogle-cloud-firestoreflutter-provider

Flutter retrieve data in a List with FutureBuilder


at the moment im trying to understand some fundamentals of retrieving data with flutter and firestore. In my case I want to retrieve data once, so I decided to choose FutureBuilder instead of StreamBuilder.

Now when I place a print statement inside my widget tree I notice, that everytime I call my function of course the whole tree is rebuilding. Now I want to use a Consumer, so that only my Listview.Builder reloads, but i can't get it work propably. The widget tree ist still rebuilding. Hopefully someone can help me out.

Consumer<SongProvider>(builder: (context, sProvider, _) {
                  return FutureBuilder(
                      future: songFuture,
                      builder: (context, snapshot) {
                      

                          switch (snapshot.connectionState) {
                            case ConnectionState.none:
                            case ConnectionState.waiting:
                              return Align(
                                alignment: Alignment.center,
                                child: CircularProgressIndicator()
                              );
                            case ConnectionState.done:
                              if (snapshot.hasError) {
                                return Text('Error: ${snapshot.error}');
                              } else {

                                return ListView.builder(
                          itemCount: snapshot.data.length,
                          itemBuilder: (context, index) {
                            return Text(
                                snapshot.data[index]['songName'].toString());
                          });
                              }
                          }

                          
                    }
                  );
            }))
      ],
    )));
  }
}

How can I make the Consumer work now? I think I need to replace it with the snapshots maybe, but i dont know how and where im getting the data from. please help


Solution

  • Create a attribute for future as Future<dynamic> yourDataFuture; and initialize it in initState as

    void initState() {
       super.initState();
       yourDataFuture= getData(); // get Data will returns a future
    }
    

    Then assign this variable as future to FutureBuilder as

    ...... rest of the code...
    
    future: yourDataFuture,
    
    ....... rest of the code....
    

    One more thing you need to handle ConnectionStates to prevent multiple calls. In your code, the future builder will call 3 times. one for none, 2nd time for waiting and third time for done.Read. So, build the list when connection state reaches done