Using RefreshIndicator with FutureBuilder (QuerySnapshot issue)

Issue

Im trying to implement the pull to refresh action, on a future builder using refresh indicator widget.
I’ve manage to get it to load correctly but when i try to refresh the list by pulling to refresh, cant get pass the issue im currently facing.

1.

late Future<QuerySnapshot> postsList;
  1. Initialize the data
void initState() {
  super.initState();

  postsList = loadPostsList();
}
  1. load data from firestore function
Future<QuerySnapshot> loadPostsList() async {
  print('Refreshing Post List...');
  keyRefresh.currentState?.show();

  final QuerySnapshot data = await FirebaseFirestore.instance
      .collection('Posts')
      .orderBy('createdAt', descending: true)
      .get();

  return data;
}
  1. Now this is where im stuck, i want add setState(() => this.postsList = data); into the loadPostsList() function like the following:
Future<QuerySnapshot> loadPostsList() async {
  print('Refreshing Post List...');
  keyRefresh.currentState?.show();

  final QuerySnapshot data = await FirebaseFirestore.instance
      .collection('Posts')
      .orderBy('createdAt', descending: true)
      .get();

  // HERE
  setState(() => this.postsList = data);

  return data;
}

but getting this error:

A value of type ‘QuerySnapshot<Object?>’ can’t be assigned to a variable of type ‘Future<QuerySnapshot<Object?>>’.

Any help is appreciate as im new to flutter and still learning :), below is the full code:

final keyRefresh = GlobalKey<RefreshIndicatorState>();
late Future<QuerySnapshot> postsList;

@override
void initState() {
  super.initState();

  postsList = loadPostsList();
}

Future<QuerySnapshot> loadPostsList() async {
  print('Refreshing Post List...');
  keyRefresh.currentState?.show();

  final QuerySnapshot data = await FirebaseFirestore.instance
      .collection('Posts')
      .orderBy('createdAt', descending: true)
      .get();

  return data;
}

FutureBuilder<QuerySnapshot>(
  future: postsList,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final List<DocumentSnapshot> documents =snapshot.data!.docs;

      return RefreshIndicator(
        key: keyRefresh,
        color: Colors.blue,
        onRefresh: loadPostsList,
        child: SingleChildScrollView(
          physics: AlwaysScrollableScrollPhysics(),
          child: Column(
            children: documents.map((doc) => new PostCard(
              author: doc['author'],
              title: doc['title'],
              description: doc['desc'],
            ),
          ).toList(),
        ),
      );
    } else if (snapshot.hasError) {
      return Text('Error!');
    } else {
      return LoadingWidget();
    }
  },
),

Solution

The error is because you defined data as type QuerySnapshot and are trying to assign it to postsList, which you defined as type Future<QuerySnapshot>. Obviously, they are different types so you can’t assign one to the other.

Don’t call setState from inside loadPostsList. Use something like:

onRefresh: () async {
  setState(() {
    postsList = loadPostsList();
  });
}

Answered By – PatrickMahomes

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *