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);
}
});