仅呈现最近的更改 Firestore + Angular 聊天应用
Only render recent changes Firestore + Angular Chat app
我使用 firestore(使用 angularfire wrapper)和 angular 创建了一个聊天应用程序,它正在运行。数据库结构是这样的。我为每个用户都有唯一的 ID。当有人(发送者)向其他人(接收者)发送消息时,我将消息添加到发送者:
collection("messages") => doc(sender's ID) => collection(receiver's ID) => doc(message ID)
此外,我将相同的消息添加到接收者:
collection("messages") => doc(receiver's ID) => collection(sender's ID) => doc(message ID)
现在,当用户(发送者)打开与另一个用户(接收者)的聊天时,我将监听器(valueChanges)附加到:
collection("messages") => doc(sender ID) => collection(receiver ID)
集合中每条消息的结构如下:
message: 'string message'
profilePic: 'url for profile pic'
senderId: 'unique id of sender'
timestamp: some timestamp
使用此配置一切正常,但存在一些问题。
- 每当添加新消息时,'valueChanges' 都会侦听更改并将值分配给数组 'chats'。 'chats' array 与 *ngFor 一起使用来显示消息的内容。当我收到更改时会出现问题,整个消息列表都会重新呈现,包括个人资料图片。理想情况下,只应呈现最近的更改。
- 无法(或我能想到的)查询每个用户的最新消息。
使用valueChanges
会很简单,但您会看到问题,而且它还需要使用数据库。所以我建议你看看 snapshotChanges.
您可以按照以下方式拆分逻辑。
- 使用
valuechanges
和 first
/或 take(1)
运算符在输入时加载所有消息。
this.messages = await this.afs.collection('messages')
.valuechanges()
.pipe(take(1))
.toPromise();
- 而且还要监听最近的变化,修改Angular这边的数组
// manage recently added messages
this.afs.collection('messages').snapshotChanges(['added'])
.pipe(takeUntil(untilFn))
.subscribe(added => {
this.messages = [...added, this.messages];
});
// manage recently removed messages
this.afs.collection('messages').snapshotChanges(['removed'])
.pipe(takeUntil(untilFn))
.subscribe(removed => {});
// manage recently modified messages
this.afs.collection('messages').snapshotChanges(['modified'])
.pipe(takeUntil(untilFn))
.subscribe(modified => {});
请注意 snapshotChanges
的 return 类型不同于 valueChanges
。
我使用 firestore(使用 angularfire wrapper)和 angular 创建了一个聊天应用程序,它正在运行。数据库结构是这样的。我为每个用户都有唯一的 ID。当有人(发送者)向其他人(接收者)发送消息时,我将消息添加到发送者:
collection("messages") => doc(sender's ID) => collection(receiver's ID) => doc(message ID)
此外,我将相同的消息添加到接收者:
collection("messages") => doc(receiver's ID) => collection(sender's ID) => doc(message ID)
现在,当用户(发送者)打开与另一个用户(接收者)的聊天时,我将监听器(valueChanges)附加到:
collection("messages") => doc(sender ID) => collection(receiver ID)
集合中每条消息的结构如下:
message: 'string message'
profilePic: 'url for profile pic'
senderId: 'unique id of sender'
timestamp: some timestamp
使用此配置一切正常,但存在一些问题。
- 每当添加新消息时,'valueChanges' 都会侦听更改并将值分配给数组 'chats'。 'chats' array 与 *ngFor 一起使用来显示消息的内容。当我收到更改时会出现问题,整个消息列表都会重新呈现,包括个人资料图片。理想情况下,只应呈现最近的更改。
- 无法(或我能想到的)查询每个用户的最新消息。
使用valueChanges
会很简单,但您会看到问题,而且它还需要使用数据库。所以我建议你看看 snapshotChanges.
您可以按照以下方式拆分逻辑。
- 使用
valuechanges
和first
/或take(1)
运算符在输入时加载所有消息。
this.messages = await this.afs.collection('messages')
.valuechanges()
.pipe(take(1))
.toPromise();
- 而且还要监听最近的变化,修改Angular这边的数组
// manage recently added messages
this.afs.collection('messages').snapshotChanges(['added'])
.pipe(takeUntil(untilFn))
.subscribe(added => {
this.messages = [...added, this.messages];
});
// manage recently removed messages
this.afs.collection('messages').snapshotChanges(['removed'])
.pipe(takeUntil(untilFn))
.subscribe(removed => {});
// manage recently modified messages
this.afs.collection('messages').snapshotChanges(['modified'])
.pipe(takeUntil(untilFn))
.subscribe(modified => {});
请注意 snapshotChanges
的 return 类型不同于 valueChanges
。