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(); //