I've been working on a realtime chat in flutterflow, which I am building from the ground up since it needs to have intergrations from other parts of the app. The chat part worked, but the main issue is that it has to load all the messages or have a hard limit, due to pagination not working with realtime in firestore.
Loading all messages of a chat at once is too slow and too many firebase reads, limiting it means older messages can't be read, and pagination can't be realtime.
At first I tried converting the following react code to flutter:
https://nunes-nelson.medium.com/flutter-firestore-pagination-and-realtime-update-a55133ff3ebd
To some degree this worked, but I ran into problems with how it displayed in a listview and with it removing older messages from realtime when new messages came in.
I also thought about trying to fix this with caching, but a problem with that is it still loading all the messages the first time you open a chat, or if you decide to switch devices. New users or users who redownloaded the app would have to reload every chat again, also being a lot of firebase reads.
After that I tried this firebase pagination package, which does work, but for some reason it only loads a new "page" once and then stops and I have not been able to figure out why.
https://pub.dev/packages/firebase_pagination
The custom widget that I'm currently using for that is:
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:firebase_pagination/firebase_pagination.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
class Chat extends StatefulWidget {
const Chat({
Key? key,
this.width,
this.height,
required this.chatMessagesRef,
required this.paginationAmount,
}) : super(key: key);
final double? width;
final double? height;
final DocumentReference chatMessagesRef;
final int paginationAmount;
@override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
late int paginationAmount;
@override
void initState() {
super.initState();
paginationAmount = widget.paginationAmount;
}
@override
Widget build(BuildContext context) {
return FirestorePagination(
limit: 15,
isLive: true,
viewType: ViewType.list,
reverse: true,
query: widget.chatMessagesRef
.collection('chatMessage')
.orderBy('uploadTime', descending: true),
itemBuilder: (context, documentSnapshot, index) {
final data = documentSnapshot.data() as Map<String, dynamic>?;
if (data == null) return Container();
String? msg = data['message'];
debugPrint(data.toString());
Timestamp timestamp = data['uploadTime'];
DateTime dateTime = timestamp.toDate();
String formattedDate =
"${dateTime.day.toString().padLeft(2, '0')}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.year}";
return ListTile(
title: Text(
msg ?? 'no message' + ' | ' + formattedDate,
),
);
},
separatorBuilder: (context, index) {
return const Divider(
height: 5,
thickness: 1,
);
},
);
}
}
This only displays the messages, since I am currently using the with flutterflow build chat to send messages and update/delete through the firebase console for testing.
Does anyone have any advise or reference how I could do this?