Firestore:如何同时收听集合和子集合
Posted
技术标签:
【中文标题】Firestore:如何同时收听集合和子集合【英文标题】:Firestore: How to listen to both collection and subcollection 【发布时间】:2022-01-19 01:11:02 【问题描述】:在 Firebase Firestore 中,我有一个集合,其中每个文档都包含一个 id 数组和一个子集合;像这样:
collection: households
>>> doc: household1, members = [1]
>>> >>> collection entries
>>> >>> >>> entry 1, <data>
>>> >>> >>> entry 2, <data>
>>> doc: household2, members = [1, 2]
>>> >>> collection entries
>>> >>> >>> entry 3, <data>
>>> >>> >>> entry 4, <data>
>>> >>> >>> entry 5, <data>
我想查询用户 1 所属的所有条目。我想对听众进行此操作,以便在 (1) 家庭发生变化或 (2) 条目发生变化时更新我的数据。
我该怎么做?
我试过先查询对应的户,然后得到对应的条目,像这样:
// Loop trough all households of user
db.collection("households")
.where("members", "array-contains", uid)
.where("status", "==", "active")
.onSnapshot((snapshotChange) =>
// Loop trough entry of each household
snapshotChange.forEach((householdsDoc) =>
db.collection("households")
.doc(householdsDoc.id)
.collection("entries")
.onSnapshot((snapshotChange) =>
snapshotChange.forEach((doc) =>
// Prepare entry
let currentDoc = doc.data();
currentDoc["id"] = doc.id;
// Handle change according to type
snapshotChange.docChanges().forEach((change) =>
console.log(change.type, "change.doc.id", change.doc.id);
if (change.type === "added")
this.entries.push(currentDoc);
else if (change.type === "modified")
let index = this.entries.findIndex(
(el) => el.id === change.doc.id
);
if (index > -1)
this.entries.splice(index, 1);
this.entries.push(currentDoc);
else if (change.type === "removed")
let index = this.entries.findIndex(
(el) => el.id === change.doc.id
);
if (index > -1)
this.entries.splice(index, 1);
);
);
);
对于这段代码,我从控制台得到这个:
如您所见,不知何故,某些 id 会多次到达。这是为什么呢?
【问题讨论】:
【参考方案1】:Firestore 中的读取和侦听器很浅。无法对家庭执行读取/查询,也无法一次性从子集合中获取条目。
您可以:
-
对家庭集合执行查询,然后单独读取每个匹配家庭文档的子集合。
将成员数据复制到子集合中的每个条目文档中,然后use a collection group query 在所有条目集合中查询您需要的成员。
这两种方法都不比另一种更好,因此请查看您的具体用例,看看什么会产生最少的读取/成本和最佳性能。
【讨论】:
感谢您的澄清。我会选择你的第二个选项(尽管我仍然觉得复制数据很奇怪:P)。从好的方面来说,查询变得更加精简。非常感谢! 这实际上是 Julian 的权衡:更多的数据重复和更复杂的写入与更快和更简单的读取。 ? 一旦你习惯了这一点,就会突然发现,NoSQL 数据库往往在读取方面的技能非常出色,而在写入方面却不是那么好。以上是关于Firestore:如何同时收听集合和子集合的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Flutter 获取 Firestore 中每个集合的子集合
如何在保持访问权限不变的同时将 Firestore 文档从一个子集合共享到另一个子集合?