【问题标题】:Flutter Firebase: Retrieve a list of documents, limited to IDs in an array?Flutter Firebase:检索文档列表,仅限于数组中的ID?
【发布时间】:2021-01-27 08:03:27
【问题描述】:

我正在开发一个 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());
}

我正在尝试做的事情是否可能?我已经搞砸了这两天,我的头要爆炸了。任何帮助将不胜感激。提前致谢。

【问题讨论】:

标签: firebase flutter google-cloud-firestore nosql


【解决方案1】:

首先,如何获取共享列表 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 执行单独的查询。

【讨论】:

  • 你让我成功了 90%,但我有一个后续问题,如果你有任何指导吗?我已经根据您的建议发布了我的新代码,并在最后提出了问题。
【解决方案2】:

你需要两个操作。

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

citiesRef.where(FieldPath.documentId, arrayContains: ['project1id', 'project2id']);

另见:

【讨论】:

  • 谢谢弗兰克。在您和 Doug Stevenson 之间,我能够回答我最初的问题。但是你们都让我注意到,基于列表的查询最多只能包含 10 个条目。这给我留下了另一个问题。如果您有任何进一步的指导,我已经发布了我的新代码和问题。再次感谢,提前。
猜你喜欢
  • 2021-01-28
  • 2020-01-05
  • 2018-12-15
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 2023-01-12
相关资源
最近更新 更多