【发布时间】:2018-04-05 11:38:12
【问题描述】:
我正在浏览 Firestore 文档和指南。下面我的代码示例使用 AngularFire2。
让我们考虑一个类似于此处提供的示例的“聊天”集合:https://firebase.google.com/docs/firestore/manage-data/structure-data
他们推荐这种结构,但我看不出他们在哪里讨论有效地获取所有数据。
每个聊天文档都有属性、成员集合和消息集合:
-
chatsCollection
-
聊天文档
- [在此处插入聊天数据字段]
-
membersCollection
-
成员文件
- [在此处插入成员数据字段]
-
成员文件
-
messagesCollection
-
消息文档
- [在此处插入消息数据字段]
-
消息文档
-
聊天文档
Firestore 查询很浅,有时可能很棒。我的理解是,没有固定的方法可以深入查询并获取嵌套集合。那么,最好的做法和最轻松的方法是什么?
目前,我正在检索快照并将其映射到具有 ID 的对象,并将嵌套的集合数据添加到具有附加查询和映射的父文档数据中,我对我的方法不满意,甚至可以做得更快具有非规范化的 Firebase 结构。
此代码示例只是映射成员,添加回消息是另一回事...
getChatsFromFirestore() {
this.chats = this.dataSvc.getChatsFromFirestore().snapshotChanges()
.map(chatSnaps => {
return chatSnaps.map(chat => {
const chatData = chat.payload.doc.data();
const chatId = chat.payload.doc.id;
return this.dataSvc.getMembersForChat(chatId)
.snapshotChanges()
.map(memberSnaps => {
return memberSnaps.map(member => {
const data = member.payload.doc.data();
const id = member.payload.doc.id;
return { id, ...data }
});
})
.map(members => {
return { chatId, ...chatData, members: members };
});
})
})
.flatMap(chats => Observable.combineLatest(chats));
}
从服务中:
getChatsFromFirestore() {
return this.fsd.collection<any>('chats');
}
getChatFromFirestoreById(id: string) {
return this.fsd.doc(`chats/${id}`);
}
getMembersForChat(chatId) {
return this.getChatFromFirestoreById(chatId).collection('members');
}
【问题讨论】:
-
我想这里有一个论点是根据实时数据库的流程复制和非规范化数据(类似于this answer),但我也希望有一个不同/更好的流程来加入数据在 Firestore 中。
-
好点,在这种情况下,我确实对数据进行了欺骗和破坏。例如,每个聊天都包含其成员,这些成员具有与 UID 匹配的文档 ID,该 UID 可用于获取该成员的所有数据,但还包含用户名。每条单独的消息还包含一个“authorName”字段和一个“sentBy”字段再次保存该用户的 UID……仍然能够在不递归调用 DB 或至少不那么冗长的情况下获取聊天室文档下的所有嵌套数据代码会很酷。
-
如果将id以
chatDocument保存为字段,则可以使用.valueChanges()获取id。这比.snapshotChanges()快。 -
如何只为用户获取相关的聊天文档?每个用户都会看到每个聊天记录吗?
-
这只是 Firebase 文档中数据的一个相关示例。为用户获取相关的聊天文档将遵循稍微不同的路径,但仍需要嵌套的顺序数据库查询。可能在其他情况下,我希望像示例中一样一次获取文档列表及其所有嵌套数据。
标签: angular typescript firebase angularfire2 google-cloud-firestore