0

I would like to implement Firebase's Infinite scrolling through the "firebase_ui_firestore" library. The goal would be to load 12 documents initially and load more once the user reaches the end. However, the problem is that all documents from the collection are loaded and displayed once the screen is opened.

Could anyone help me with fixing the issue?

My code is the following:

import 'package:flutter/material.dart';
import 'package:firebase_ui_firestore/firebase_ui_firestore.dart';
import 'package:myapp/constants.dart';
import 'package:myapp/models/video_tile.dart';
import 'package:myapp/widgets/videos/profile_video_tile.dart';


class InfiniteScrollingScreen extends StatefulWidget {
  final String userUid;

  const InfiniteScrollingScreen({required this.userUid, Key? key}) : super(key: key);

  @override
  State<InfiniteScrollingScreen> createState() => _InfiniteScrollingScreenState();
}

class _InfiniteScrollingScreenState extends State<InfiniteScrollingScreen> {

  @override
  Widget build(BuildContext context) {
    final query = firestore
        .collection(videosPath)
        .where('uid', isEqualTo: widget.userUid)
        .withConverter(
      fromFirestore: (snapshot, _) => VideoTile.fromJson(snapshot),
      toFirestore: (user, _) => user.toJson(),
    );

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      child: FirestoreQueryBuilder<VideoTile>(
        query: query,
        pageSize: 12,
        builder: (context, snapshot, _) {
          if (snapshot.isFetching) {
            return const Center(child: CircularProgressIndicator(),);
          } else if (snapshot.hasError) {
            return Text("Something went wrong! ${snapshot.error}");
          } else {
            return GridView.builder(
              itemCount: snapshot.docs.length,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                crossAxisSpacing: 8.0,
                mainAxisSpacing: 8.0,
                childAspectRatio: 1.0,
              ),
              physics: const NeverScrollableScrollPhysics(),
              itemBuilder: (context, index) {
                if (snapshot.hasMore && index + 1 == snapshot.docs.length) {
                  snapshot.fetchMore();
                }

                final videoTile = snapshot.docs[index].data();

                return ProfileVideoTile(
                  thumbnailUrl: videoTile.thumbnail,
                  videoId: videoTile.id,
                );
              },
            );
          }
        },
      ),
    );
  }
}

I already tried to fix the issue by removing "shrinkWrap: true", a SingleChildScrollView widget, a SafeArea widget, and a CupertinoPageScaffold widget. I don't know how to approach this problem otherwise.

I would appreciate your help!

Thanks in advance!

  • check this it may help you https://stackoverflow.com/questions/52275624/flutter-load-limited20-documents-records-and-display-in-list-view-at-a-time – Ahmad Raza Dec 26 '22 at 11:56
  • Your code doesn't implement pagination yet, so that explains why you get all documents. I recommend starting with the Firebase documentation on [cursor based pagination](https://firebase.google.com/docs/firestore/query-data/query-cursors) and looking at some of the many existing [questions about pagination in Firestore](https://stackoverflow.com/search?q=%5Bgoogle-cloud-firestore%5D+pagination). – Frank van Puffelen Dec 26 '22 at 16:05
  • Is additional pagination required, Frank? According to the documentation from firestore (https://pub.dev/packages/firebase_ui_firestore), pageSize gives the initial number of documents and once the end was reached another batch should be loaded, at least from my understanding. I thought it might be bc of shrinkWrap expecting all documents, but I already removed it and it is still not working... Thanks for your reply! – mike-dev1 Dec 26 '22 at 16:25

1 Answers1

0

you can use .limit() on your query just create new variable and just put the variable on the limit method

int docLimit = 12; // initial 12    
firestore.collection(videosPath).where('uid', isEqualTo: widget.userUid).limit(docLimit)....

and then just add the docLimit value when you scroll and hit the bottom

you can watch here as your refference How to check if scroll position is at top or bottom in ListView?