Flutter stream deletion issue

136 Views Asked by At

I am working on Flutter application that uses Firestore. I have shown my documents in app with list view. I can update the documents and it appears immediately in app thanks to Flutter stream. However, I'm having an issue when I'm deleting a document. Seems deletion is working fine in reality, but the display in app is showing wrong information. For example, I delete a document at index 1, but always the document at last index is removed. Seems the event coming from FireStore stream just updating number of documents in stream, the list view is showing the information through another widget (like customer List tile) the information for each index is not updated correctly. Below is my code:

    class _BudgetSummaryState extends State<BudgetSummary> {
  Stream<QuerySnapshot> getSummaries() => FirebaseFirestore.instance
      .collection('Users')
      .doc(FirebaseAuth.instance.currentUser!.phoneNumber)
      .collection('UserDBs')
      .snapshots();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MyAppBar('Summary'),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          Navigator.of(context).pushNamed('/Update_Edit_Screens/AddNewBudget');
        },
        label: const Text('Add new'),
        icon: const Icon(Icons.add),
      ),
      body: SafeArea(
          child: StreamBuilder<QuerySnapshot>(
              stream: getSummaries(),
              builder: (context, snapshot) {
                if (snapshot.hasError) {
                  return const Center(
                    child: Text('Something went wrong, please try again later'),
                  );
                }
                if (snapshot.hasData) {
                  var data = snapshot.data;
                  if (data == null) {
                    return const Center(
                      child: Text('Add you first budget/expense tracker'),
                    );
                  } else {
                    return ListView.builder(
                        itemCount: data.docs.length,
                        itemBuilder: ((context, index) {
                          Color col =
                              index % 2 == 0 ? Colors.lightBlue : Colors.lime;
                          return SummaryWidget(data.docs[index], col);
                        }));
                  }
                } 

I did a workaround by reloading the whole page, that is rebuilding the complete route. But somehow I feel it kills the purpose of using stream. Please advise if I'm missing something?

1

There are 1 best solutions below

0
On

Classic problem of data removal in Flutter.

You need to provide Key for each list item. You can use ValueKey with can take some unique id for each list item. Something like

return SummaryWidget(key:ValueKey(data.docs[index].id), data.docs[index], col);

Let me know if you want to know the reasoning, I will update here.