Home > Blockchain >  Flutter: StreamBuilder into ListView doubling list items when adding to it
Flutter: StreamBuilder into ListView doubling list items when adding to it

Time:09-27

So I have a StreamBuilder which runs a query to Cloud Firestore for a list of documents. I then make each document into an item in my ListView and that works fine.

I am trying to edit the code because I want to add a search filter. I don't want to re-call data from Cloud Firestore each time a user is filtering the list.

So I decided to load all the data from Cloud Firestore into a list then use that list to build the ListView:

    builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
      //widget build for complated call
      if (snapshot.hasData) {
        for (var i = 0; i < snapshot.data!.docs.length; i  ) {
          DocumentSnapshot doc = snapshot.data!.docs[i];
          GearItem tempItem = GearItem(
            doc['itemName'],
            doc['itemTemperatureRating'],
            doc['itemType'],
            doc['itemVolume'],
            doc['itemWeight'],
            doc['itemWeightFormat'],
            doc['manufacturer'],
            doc['packCategory'],
            doc.reference.id,
            doc['itemTempFormat'],
            doc['itemVolumeFormat'],
            doc['link'],
          );
          _listViewItems.add(tempItem);
        }

        //todo: cange ListView Builder to use new list
        return ListView.builder(
            itemCount: _listViewItems.length,
            itemBuilder: (context, index) {

This works initially. While the stream is open if I add an item to the list then I get the list loaded twice on itself and double all the items.

I cant figure out why the items get re-added to the _listViewItems list when the stream auto updates.

Updated:

Stream section of StreamBuilder:

stream: db
    .collection('GearLockerItems')
    .where('userId', isEqualTo: userID)
    .orderBy('itemName')
    .snapshots(),

Appreciate if someone can advise. Thank you in advance!

CodePudding user response:

Every time there's a change to the data in Firestore, the stream fires an event with a QuerySnapshot that contains all data for that query/collection in the database.

The best option is to process snapshot.data!.docChanges, which allows you to see what changed between this QuerySnapshot and the previous one.

A much simpler fix is to keep processing the snapshot.data!.docs as you already, but clear _listViewItems before you process the new snapshot:

builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
  // clear previous results
  _listViewItems.clear(); //            
  • Related