问题描述
我正在使用Flutter应用程序,每个用户都可以创建项目,并与其他用户共享项目。我创建了一个“共享”集合,其中每个用户的ID是一个文档,并且在该文档中,像这样收集了与该用户共享的所有项目ID,并带有一个布尔值,表示是否已共享该共享。接受了:
接下来,我创建了项目本身的集合,如下所示:
现在,我想查询“项目”集合,并仅返回给定用户“共享”列表中的项目。首先,如何获得共享列表ID中的每个文档?其次,是否可以使用.where()
子句将该ID与List的内容进行比较?
我一直在尝试类似的方法,但无济于事:
Stream<List<Map<String,dynamic>>> getlistofProjectsForUser({@required List<String> shares}) {
var ref = _firestore.collection('projects');
return ref
.where(shares,arrayContains: ref.id)
.snapshots()
.map((QuerySnapshot snapshot) => snapshot.docs.map((DocumentSnapshot doc) => doc.data()).toList());
}
我也尝试过:
Stream<List<Map<String,dynamic>>> getlistofProjectsForUser({@required List<String> shares}) {
var ref = _firestore.collection('projects');
return ref
.where(shares,arrayContains: Fieldpath.documentId)
.snapshots()
.map((QuerySnapshot snapshot) => snapshot.docs.map((DocumentSnapshot doc) => doc.data()).toList());
}
我正在尝试做的可能吗?我已经把这弄乱了两天,我的脑袋爆炸了。任何帮助将不胜感激。预先感谢。
解决方法
首先,如何获得共享列表ID中的每个文档?
为此,您需要实际查询整个集合。您可以迭代结果以收集每个文档的ID。没有简单的方法可以直接从Web和移动客户端代码中直接获取ID列表。参见:How to get a list of document IDs in a collection Cloud Firestore?
其次,是否可以使用.where()子句将该ID与List的内容进行比较?
如果您的内存中有文档ID字符串列表,该列表可以是任意长度,则需要针对每个ID为“ projOwner”执行查询过滤项目。 Firestore中没有类似SQL的联接,因此您不能简单地通过单个查询将两个集合联接在一起。
这是您执行单个操作的方法-您必须调出要过滤的字段名称:
firestore
.collection("projects")
.where("projOwner",isEqualTo: id)
如果列表中有10个或更少的共享ID,则可以使用“ in”查询从项目中查找匹配项,它将不再起作用。
firestore
.collection("projects")
.where("projOwner",whereIn: listOfIds)
因此,如果您认为列表可能大于10,则应该从对每个共享ID进行单独查询开始。
,您需要执行两项操作。
- 为用户阅读文档,以确定项目ID列表。
- 对与这些ID匹配的项目文档执行
in
query。in
运算符最多接受10个ID,因此,如果您有10个以上的项目,则需要多个查询并将结果合并到应用程序代码中。
var citiesRef = db.collection("projects");
citiesRef.where(FieldPath.documentId,["project1id","project2id"])
另请参阅:
-
where(field,whereIn:)
operation的FlutterFire文档 -
FieldPath.documentId
field的FlutterFire文档