Flutter Firebase:检索文档列表,仅限于数组中的 ID?

Con*_*eeC 4 nosql firebase flutter google-cloud-firestore

我正在开发一个 Flutter 应用程序,每个用户都可以创建项目并与其他用户共享项目。我创建了一个“共享”集合,其中每个用户的 ID 都是一个文档,在该文档中,与该用户共享的所有项目 ID 都像这样收集,并使用一个布尔值来表示共享是否已被共享。尚未接受:

股票收藏

接下来,我创建了项目本身的集合,如下所示:

项目集合

现在,我想查询“项目”集合并仅返回给定用户的“共享”列表中的项目。首先,如何获取共享列表中每个文档的ID?其次,是否可以使用子句将该 ID 与列表的内容进行比较.where()

我一直在尝试这样的事情,但没有成功:

  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());
  }
Run Code Online (Sandbox Code Playgroud)

我也尝试过这个:

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());
}
Run Code Online (Sandbox Code Playgroud)

我想做的事情可能吗?我已经搞砸了两天了,我的头爆炸了。任何帮助将不胜感激。提前致谢。

Fra*_*len 7

您需要进行两次手术。

  1. 阅读用户文档,以确定项目 ID 列表。
  2. 查询in这些 ID 匹配的项目文档。该in运算符最多接受 10 个 ID,因此如果您有超过 10 个项目,您将需要多个查询并将结果合并到应用程序代码中。
var citiesRef = db.collection("projects");

citiesRef.where(FieldPath.documentId, arrayContains: ['project1id', 'project2id']);
Run Code Online (Sandbox Code Playgroud)

另请参阅:


Dou*_*son 5

首先,如何获取共享列表中每个文档的ID?

为此,您需要实际查询整个集合。您可以迭代结果以收集每个文档的 ID。没有简单的方法可以直接从 Web 和移动客户端代码获取 ID 列表。请参阅:如何获取集合 Cloud Firestore 中的文档 ID 列表?

其次,是否可以使用 .where() 子句将该 ID 与列表的内容进行比较?

如果内存中有一个任意长度的文档 ID 字符串列表,则需要为每个单独的 ID 执行“projOwner”的查询过滤项目。Firestore 中没有类似 SQL 的联接,因此您不能简单地使用单个查询将两个集合联接在一起。

以下是执行单个操作的方法 - 您必须调用要过滤的字段的名称:

firestore
    .collection("projects")
    .where("projOwner", isEqualTo: id)
Run Code Online (Sandbox Code Playgroud)

如果列表中的共享 ID 不超过 10 个,则可以使用“in”查询从项目中查找匹配项,并且不再适用。

firestore
    .collection("projects")
    .where("projOwner", whereIn: listOfIds)
Run Code Online (Sandbox Code Playgroud)

因此,如果您认为列表可能大于 10,那么您应该首先对每个共享 ID 执行单独的查询。