Search code examples
firebaseflutterlistview

how to change values dynamically in a flutter list view and firebase as well


I am incrementing the whole list because of the for loop on all the documents but can't solve how to increment/decrement the specific index, please tell me how to do that. I have the following code inside streame builder and list view builder.

Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      InkWell(
        onTap: () async {
          final QuerySnapshot result =
              await FirebaseFirestore.instance
                  .collection('mynamazstatus')
                  .get();
          final List<DocumentSnapshot> documents =
              result.docs;
          // ignore: avoid_print
          for (var data in documents) {
            FirebaseFirestore.instance
                .collection('mynamazstatus')
                .doc(data.id)
                .update({
              praises['count']: FieldValue.increment(1)
            });
          }
        },
        child: const Icon(
          Icons.arrow_drop_up,
          size: 20,
        ),
      ),
      InkWell(
        onTap: () async {
          final QuerySnapshot result =
              await FirebaseFirestore.instance
                  .collection('mynamazstatus')
                  .get();
          final List<DocumentSnapshot> documents =
              result.docs;
          // ignore: avoid_print
          for (var data in documents) {
            FirebaseFirestore.instance
                .collection('mynamazstatus')
                .doc(data.id)
                .update({
              praises['count']: FieldValue.increment(-1)
            });
          }
          },
        child: const Icon(
          Icons.arrow_drop_down,
          size: 20,
        ),
      ),
    ],
  ),

It works in the app UI as well as in firebase, but for all docs as per one tap.


Solution

  • You could literally add a field called index to your document and use that as a reference to fetch the document that matches on that index. Let's say you're rendering the InkWell buttons inside a ListView.builder after fetching all documents from a StreamBuilder widget, as in:

    StreamBuilder(
         stream: FirebaseFirestore.instance.collection('mynamazstatus').snapshots(),
         builder: (context, snapshot) {
            
           if (snapshot.hasData) {
             List<DocumentSnapshot> docs = (snapshot.data! as QuerySnapshot).docs;
    
             // return your documents in a list, for example
             return ListView.builder(
                itemCount: docs.length,
                itemBuilder: (context, index) {
                   // ... use this index to both pull the document and to save to it as well
    
                  DocumentSnapshot docRef = docs.where((d) => d.data()['index'] == index).first;
    
                  // now, use the docRef to render your components, as well as
                  // hook it up to the InkWell
    
                }
             )
           }
    
           return Center(child: CircularProgressIndicator());
       }
    )
    

    Then when you build your widgets inside the ListView.builder, use the reference to the fetched DocumentSnapshot by index (docRef) and you can update it as such:

    InkWell(
      onTap: () async {
        FirebaseFirestore.instance
          .collection('mynamazstatus')
          .doc(docRef.id)
          .update({
            praises['count']: FieldValue.increment(-1)
          });                         
      },
        child: const Icon(
        Icons.arrow_drop_down,
        size: 20,
      ),
    )