从嵌套在Firestore中的文档中的集合中获取数据的最佳方法是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从嵌套在Firestore中的文档中的集合中获取数据的最佳方法是什么?相关的知识,希望对你有一定的参考价值。
我正在浏览Firestore文档和指南。我下面的代码示例使用AngularFire2。
让我们考虑一个类似于这里提供的例子的“聊天”集合:https://firebase.google.com/docs/firestore/manage-data/structure-data
他们推荐这种结构,但我不知道他们在哪里讨论有效地获取所有数据。
每个聊天文档都有属性,成员集合和消息集合:
- chatsCollection chatDocument [在这里插入聊天数据字段] membersCollection memberDocument [在此处插入会员数据字段] messagesCollection messageDocument [在此处插入消息数据字段]
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');
}
您发布的方法似乎可行,对于大型聊天应用程序,您可能不希望跟踪每个聊天室中发生的每个事件,因为这可能是大量数据。相反,最好只订阅所需内容并使用云功能和云消息处理定期更新。
通过使用辅助函数observeCollection
以及小代码重构,它将清理服务并为每个聊天室创建observable,这些聊天室在订阅之前将处于非活动状态。
class Service {
// db is plan firestore / no angularfire
db: firebase.firestore.Firestore;
loadChatrooms() {
const chatsRef = this.db.collection('chats');
return observeCollection(chatsRef)
.pipe(
map(chats => {
return chats.map(chat => {
return {
chat,
members$: this.observeCollection(chat.ref.collection('members')),
messages$: this.observeCollection(chat.ref.collection('messages')),
};
})
}),
);
}
// Takes a reference and returns an array of documents
// with the id and reference
private observeCollection(ref) {
return Observable.create((observer) => {
const unsubscribeFn = ref.onSnapshot(
snapshot => {
observer.next(snapshot.docs.map(doc => {
const data = doc.data();
return {
...doc.data(),
id: doc.id,
ref: doc.ref
};
}));
},
error => observer.error(error),
);
return unsubscribeFn;
});
}
}
在应用程序中,您只能观察当前选定的聊天室成员和消息,这将保存数据。由于此帖子标有Angular异步管道,因此可以通过自动手动下标来帮助切换。
在您的组件中:
this.currentChat$ = combineLatest(
service.loadChatrooms(),
currentlySelectedRoomId
).pipe(
map(([chats, selectedRoomId]) => {
return chats.first(chat => chat.id === selectedRoomId)
})
);
在您的模板中:
<div *ngIf="currentChat$ as currentChat">
{{ currentChat.name }}
<div *ngIf="currentChat.members$ as members">
<div *ngIf="let member of members">
{{ member.name }}
</div>
</div>
<div *ngIf="currentChat.messages$ as messages">
<div *ngIf="let message of messages">
{{ message.content }}
</div>
</div>
</div>
以上是关于从嵌套在Firestore中的文档中的集合中获取数据的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章
使用 ionic 3 中的 Angularfire2 从 Firestore 获取集合文档的 ID [重复]
在 Firestore 中使用 Angular 删除集合中的文档