我找不到这个问题的答案或解决方法,但是基本上我正在尝试建立一个分页的聊天程序,一旦打开聊天程序,当我向上滚动时,它会捕获10条最近的消息并存储在设备上使用相同功能可以再抓10个。我有一个实时侦听器,它也可以侦听传入的消息,当用户收到另一个用户发送的消息时,该侦听器也起作用,当我发送消息时会出现问题。
通过一些调试,我发现仅当我发送消息并且该消息通过实时侦听器传入时,DocumentSnapshot的“ createdAt”值才为null。但是在ui上,时间显示正确,如在Firestore控制台上显示的那样。我读到设置服务器时间戳记需要花费一些时间,但是ui会显示该时间戳记。因此,当我使用.startAfterDocument(chat.messages.last.docSnap)
时,它不起作用,因为它仅在我发送消息时才检索所有消息,但是当我从其他用户那里收到消息时,它可以正常工作。但是,当我使用.startAfter([chat.messages.last.createdAt])
时,它包括流中的最后一条消息,例如:
// Loads previous messages
[
'6',
'7',
'8',
'9',
'10',
]
// Starts listening to incoming messages after the message 10 document snapshot
// (I'm including the actual docSnap in the message model)
11 // Message sent by other user with a createdAt value in the docSnap
12 // Message sent by me with the createdAt value in the docSnap being null, but UI shows the time...
我尝试为文档快照中的createdAt值分配一个值,但是它不起作用。如果.startAfter([chat.messages.last.createdAt])
是目前唯一的处理方式,那么由于.startAfterDocument(chat.messages.last.docSnap)
仅在接收消息时有效,而在发送消息时中断,如何避免再次显示最后一个文档呢?
代码:
StreamSubscription messagesLive({
Chat chat,
onEmpty(),
onAdded(Message m),
onModified(Message m),
onRemoved(Message m),
onFailure(e),
}) =>
Services().crud.readLive(
stream: (chat.messages.isEmpty
? APIs()
.chats
.collection
.doc(chat.chatID)
.collection(Constants.messages)
.orderBy('createdAt', descending: false)
: APIs()
.chats
.collection
.doc(chat.chatID)
.collection(Constants.messages)
.orderBy('createdAt', descending: false)
.startAfter([chat.messages.last.createdAt]) // works but doesn't start after, it includes the message
// .startAfterDocument(chat.messages.last.ds) // works only when user is receiving messages but goes null when the last message is the message sent by the user himself
)
.snapshots(includeMetadataChanges: true),
onEmpty: () => onEmpty(),
onAdded: (m) => onAdded(Message.model(
ds: m, // Document Snapshot
id: m.id,
map: m.data(),
)),
onModified: (m) => onModified(Message.model(
ds: m,
id: m.id,
map: m.data(),
)),
onRemoved: (m) => onRemoved(Message.model(
ds: m,
id: m.id,
map: m.data(),
)),
onFailure: (e) => onFailure(e),
);