我已经使用StreamProvider实现了带有分页的聊天,它工作正常。但是,如果我没有正确地实施,我会担心成本和思想,因为我没有使用startAfter
方法,而只是使用限制。
这是我的代码:
int documentLimit = 20;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
child: Consumer<ChatProvider>(builder: (context, chatProvider, child) {
bool isFirstSender = true;
if (chatProvider.selectedChatModel != null) {
isFirstSender = chatProvider.selectedChatModel.uids[0] == user.uuid;
}
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomInset: true,
appBar: ApplicationBar.getChatAppBar(context,
userId: chatProvider.selectedChatModel.targetId),
body: StreamProvider<ChatModel>.value(
catchError: (context, object) {
print(object);
return;
},
value: Provider.of<ChatProvider>(context, listen: false)
.streamChatDetail(
chatProvider.selectedChatModel.id, isFirstSender),
child: StreamProvider<List<MessageModel>>.value(
value: Provider.of<ChatProvider>(context, listen: false)
.streamMessages(chatProvider.selectedChatModel.id,
isFirstSender, documentLimit),
child: ... /// The content
然后我有这样的滚动侦听器:
_scrollController.addListener(() {
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
if (maxScroll == currentScroll) {
setState(() {
documentLimit = documentLimit + 20;
});
}
});
这是流:
Stream<List<MessageModel>> getMessages(
String uid, bool isFirstSender, int documentLimit) {
if (uid != null && uid.isNotEmpty) {
final DocumentReference documentReference =
Firestore.instance.collection('user_chats').document(uid);
Query chatDetailQuery = documentReference
.collection("chats")
.orderBy("date", descending: true)
.reference()
.limit(documentLimit);
Stream<QuerySnapshot> chatSnapshots = chatDetailQuery.snapshots();
return chatSnapshots.map((listChats) => listChats.documents.map((doc) {
MessageModel messageModel = MessageModel.fromJson(doc.data);
return messageModel;
}).toList());
}
return Stream.empty();
}
我的问题是:
首先,我已加载20条聊天消息,然后滚动到顶部并重新加载20条其他聊天消息。读取的交易总数将是40或60(因为20 + 40)?
如果第一个问题的答案是60,那么如何正确实现StreamProvider的分页?
答案 0 :(得分:0)
Firestore如果需要代表您在服务器上阅读文档,则对文档收取费用。如果启用了磁盘缓存(在iOS和Android上默认为磁盘缓存),则在您描述的情况下第二次阅读相同的文档时,它们将来自本地缓存。在这种情况下,您无需为这些读取付费。