0
votes

I am working on chat app and I am trying to use pagination to retrieve a limited amount of data from the firestore and retrieve the rest when the user keeps scrolling , I also want to listen for the latest changes in the database and display it to the user. I tried doing this by creating a Stream class that contains a snapshot listener in the constructor and adds any new changes to the stream controller, it also has a method that retrieves paginated data and adds it to the stream controller when the user is scrolling. The problem is when the data is retrieved from the database and added to the stream controller it replaces the previous data instead of adding to it. Below is the class I created

class ChatStream {
  final String messageId;
  final _controller = StreamController<QuerySnapshot>();
  var _snapshots;
  
  ChatStream({this.messageId}) {
    _snapshots = FirebaseFirestore.instance
        .collection("chats")
        .doc(messageId)
        .collection("messages")
        .orderBy("time", descending: false)
        .limitToLast(10)
        .snapshots();

    _snapshots.listen((onData) {
      _controller.sink.add(onData);
    });
  }
  getChats(DocumentSnapshot lastDocument) async {
    FirebaseFirestore.instance
        .collection("chats")
        .doc(messageId)
        .collection("messages")
        .orderBy("time", descending: false)
        .endBeforeDocument(lastDocument)
        .limitToLast(100)
        .snapshots()
        .forEach((action) {
      _controller.sink.add(action);
    });
  }

  Stream get stream {
    return _controller.stream;
  }
}

I created an object of type ChatStream called c , I then got the stream using c.stream to use in a streambuilder and i called the getChats method using a scroll listener in the initState method like so

 _scrollController.addListener(() {
      double maxScroll = _scrollController.position.minScrollExtent;
      double currentScroll = _scrollController.position.pixels;
      double delta = MediaQuery.of(context).size.height * 0.20;
      if (maxScroll == currentScroll) {
     
      c.getChats(lastDocument);
      }


    });
1
The Firestore APIs do not at all make it easy to perform both pagination and get realtime updates at the same time. If you want to do this correctly, you're going to have to put a lot of effort into adding listeners to each page of data separately, and handle all the edge cases for when the query results change positions.Doug Stevenson
Oh okay that sounds very complex but thanksV-Ghost

1 Answers

0
votes

The Firestore APIs do not at all make it easy to perform both pagination and get realtime updates at the same time. If you want to do this correctly, you're going to have to put a lot of effort into adding listeners to each page of data separately, and handle all the edge cases for when the query results change positions