【发布时间】:2021-11-13 13:57:07
【问题描述】:
我正在使用Firebase Realtime DB 实现聊天。有一个要求,有些聊天室默认可以显示新消息,但不同聊天室的消息必须先获得批准才能显示。
Firebase 中的 DB 结构嵌套如下:
/chat/$roomID/$messageID/
每个消息对象的结构如下:
{
user: string
content: string
isApproved: boolean
clientStamp: number // client-side unix timestamp
serverStamp: number // server-side unix timestamp, via `firebase.database.ServerValue.TIMESTAMP`
}
只有默认显示的聊天室会很容易 - 我会通过 serverStamp 订购数据:
let query = DBConn.ref('chat/' + roomID).orderByChild('serverStamp').limitToLast(50);
query.on("value", snapshot => {
// set the list of messages to display
this.appendSnapshot(snapshot);
});
然而,批准优先规则使这种方法变得困难。显而易见的解决方案是只显示属性isApproved 设置为true 的消息。但是,如果我要查询按时间戳排序的最后 N 条消息,并且有人会发布 N 条未批准的消息,那么这将从查询结果中删除任何已批准的消息,并且聊天将是空的。 Realtime DB有以下限制,无法同时通过时间戳+isApproved查询:
一次只能使用一种排序方式
所以现在我正在通过以下方式解决它:
- 消息按
clientStamp(客户端unix时间戳)而不是serverStamp排序 - 在向服务器发送新消息时,我将
clientStamp的值除以 2,这意味着这些新消息永远不会从查询结果中排除已经批准的旧消息(因为它们的时间戳具有更高的值) - 当消息被批准时,
clientStamp的值被设置为firebase.database.ServerValue.TIMESTAMP(服务器端时间),这会将其推到聊天查询的顶部 (orderByChild('serverStamp'))
...但这是一个相当快速的解决方法。有什么方法可以让默认显示和批准优先的聊天室都很好地工作?
【问题讨论】:
标签: javascript firebase firebase-realtime-database