在不循环的情况下查询 Firestore 集合中的所有文档

Posted

技术标签:

【中文标题】在不循环的情况下查询 Firestore 集合中的所有文档【英文标题】:Query all Documents in a Firestore Collection without Looping 【发布时间】:2018-03-22 10:52:25 【问题描述】:

我一直在努力将一个小型 Firebase 项目转换为新的、类似的 Firestore 数据库,因为它更易于查询,但我遇到了一个简单的查询问题。

我正在尝试获取集合中的所有文档,如果每个文档都是一个俱乐部并且集合是所有俱乐部。

在 Firebase 中,我能够执行以下操作:

export function fetchClubs() 
    const Club = firestore.ref('clubs');
    return dispatch => 
        Club.on('value', snapshot => 
            dispatch(
                type: FETCH_CLUBS,
                payload: snapshot.val()
            )
        )
    

snapshot 将包含我需要的所有信息。

我正在尝试使用 Firestore 复制此内容,但只能遇到一种解决方案,该解决方案涉及制作一个新数组并循环遍历结果,然后将每个结果添加到该数组中。

这是我尝试使用稍有不同的 Firestore 语法的 Firestore

export function fetchClubsStore() 
    const Clubs = firestore.collection('clubs');
     return dispatch => 
        Clubs.get().then(querySnapshot => 
            console.log("clubs snapshot: ", querySnapshot)
            dispatch(
                type: FETCH_CLUBS,
                payload: querySnapshot.val()
            )
        )
    

如果您有任何想法,我们将不胜感激所有帮助!谢谢!

(这是我的第一篇 *** 帖子,放轻松!:))

编辑:

Firestore 文档中有关如何获取集合中所有文档的示例。

db.collection("cities").where("capital", "==", true)
.get()
.then(function(querySnapshot) 
    querySnapshot.forEach(function(doc) 
        console.log(doc.id, " => ", doc.data());
    );
)
.catch(function(error) 
    console.log("Error getting documents: ", error);
);

编辑2:

我使用 .docs 和 .data() 将文档放入可用数组的新解决方案。似乎仍然效率低下,因为我必须遍历文档并一一提取可用信息。

export function fetchClubsStore() 
const Clubs = firestore.collection('clubs');
var clubs = [];
return dispatch => 
    Clubs.get().then(querySnapshot => 
        console.log("clubs snapshot: ", querySnapshot.docs)
        _.each(querySnapshot.docs, function(data)
            clubs.push(data.data());
        )
        dispatch(
            type: FETCH_CLUBS,
            payload: clubs
        )
    )

【问题讨论】:

您是否尝试过将查询与所有 Redux 操作的噪音分开处理?此示例仅使用涉及的数据库而不是您的应用程序状态来解决问题会容易得多。 我不明白您要解决什么问题(我在您的任何一个代码 sn-ps 中都看不到任何循环)。对于它的价值,querySnapshot.val() 是无效的,因为 Firestore 中的 QuerySnapshot 上没有 .val 方法。您可能希望 .docs 用于 QuerySnapshot 中的 DocumentSnapshot 对象数组或其他内容,但您的问题并不清楚。 @MichaelLehenbauer 我在当前的解决方案尝试中没有使用循环,但在我的原始帖子的编辑中提供了我正在谈论的那种循环的示例。我能够使用您建议的 .docs 方法获取 DocumentSnapshot 对象的数组,但是在我遍历它并单独获取每个文档的 .data() 之前,这些数据似乎并不是特别有用。有没有更好的方法将文档中的信息放入可用的数组中?谢谢。 @AustinWrenn 你可以使用var clubs = querySnapshot.docs.map(doc => doc.data()); 来节省一些代码。 @MichaelLehenbauer 谢谢你! ;) 【参考方案1】:

Firebase 实时数据库和 Firestore 的区别在于 RTDB 基本上只是一个云托管的 JSON 对象。所以没有文档的概念,也没有数据的集合。

您从 RTDB 检索的查询快照中的值对象只是一个 JSON 对象。因此,您可以通过它们的键访问一级节点(也可以通过它们的键访问任何级别节点)

如果您来自 RTDB,您会注意到 Cloud Firestore 具有集合和文档的区别。因此,您的查询结果本质上将是数据集合,而不是 JSON 对象。从查询中检索到的文档不能作为单个大 JSON 对象抓取。

循环查询结果是使用 Cloud Firestore 的正确方法。

【讨论】:

是的,有道理,尽管从体验的角度来看,他们当前的 API 仍然很糟糕。

以上是关于在不循环的情况下查询 Firestore 集合中的所有文档的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用index.js文件中的触发器功能的情况下从Firestore数据库读取数据?

我们可以在不重新设置整个适配器的情况下更新 Firestore 回收器适配器的查询吗?

如何在不重新加载页面的情况下更新从 firestore 检索到的标记在我的地图上?

用于列表构建的 Flutter 中的 Firestore 嵌套查询

在不循环的情况下连接单列中的记录?

区分 Firestore 中的第一次查询快照和更改侦听器