Archangel
Archangel

Reputation: 192

async function that gets data from firestore executing multiple times in dart/flutter

I have a piece of code here that is supposed to get some data from firebase firestore and add that data to a list which is then in turn is used by listview.builder to update the ui with the list of items. But somehow, the same data keeps getting added to the list over and over again. I put a print statement and i can see that the code inside the "then" function keeps executing over and over. How do i stop this from happening? Thanks in advance

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import '../models/reportmodel.dart';
import 'package:flutter/material.dart';

class AllReports extends StatefulWidget {
  @override
  _AllReportsState createState() => _AllReportsState();
}

class _AllReportsState extends State<AllReports> {
  List<Report> reportList = [];
  bool isLoading = true;

  @override
  Widget build(BuildContext context) {
    getData();
    return (isLoading)
        ? buildLoading()
        : ListView.builder(
            padding: EdgeInsets.all(20),
            itemBuilder: (context, index) {
              return Container(
                width: double.infinity,
                height: 140,
                child: Column(
                  children: [
                    Text(
                      "Complaint ID: " + reportList[index].getComplaintHash(),
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                    Text(
                      "Name: " + reportList[index].getComplainantName(),
                    ),
                    Text("Time: " + reportList[index].getComplaintTime()),
                  ],
                ),
              );
            },
            itemCount: reportList.length);
  }

  Widget buildLoading() => Stack(
        fit: StackFit.expand,
        children: [
          Center(child: CircularProgressIndicator()),
        ],
      );

  void getData() async {
    final user = FirebaseAuth.instance.currentUser;
    final snapshot = await FirebaseFirestore.instance
        .collection(user.email)
        .getDocuments()
        .then((snapshot) {
      for (int i = 0; i < snapshot.documents.length; i++) {
        reportList.add(Report.addData(
            snapshot.documents[i].id.toString(),
            snapshot.documents[i].data()["name"].toString(),
            snapshot.documents[i].data()["contact"].toString(),
            snapshot.documents[i].data()["time"].toString(),
            snapshot.documents[i].data()["description"].toString(),
            snapshot.documents[i].data()["additional_info"].toString()));
      }
      this.setState(() {
        isLoading = false;
      });
    });
  }
}

Upvotes: 0

Views: 866

Answers (1)

Peter Haddad
Peter Haddad

Reputation: 80914

It's getting executed over and over again, because you are calling the method getData() inside the build(), and everytime you call setState then it issues another build.Therefore, the method getData() will keep executing and retrieving the data.

You should use FutureBuilder widget to handle asynchronous operations.

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

Upvotes: 1

Related Questions