【问题标题】:Get data from a firestore nested query从 Firestore 嵌套查询中获取数据
【发布时间】:2021-01-10 03:21:06
【问题描述】:

我正在尝试获取社区的帖子并通过对每个帖子进行嵌套查询来获取帖子制作者数据,因此我将地图的匿名函数设为异步,所以我必须返回一个承诺,这就是问题所在,我想要返回值的对象而不是承诺,我该如何解决?

export const getComPosts = (comId) => async (dispatch, getState) => {
    try {
        dispatch({ type: POST_LIST_REQUEST })

        await firestore.collection('comPosts').where('comId', '==', comId).onSnapshot(snap => {
            const posts = snap.docs.map(async doc => {
                const { userId } = doc.data()

                const { avatar, displayName } = await (await firestore.collection('users').doc(userId).get()).data()

                return { ...doc.data(), avatar, displayName } // I wanna return this object directly not a promise
            })

            dispatch({ type: POST_LIST_RESPONSE, payload: posts })
        })
    } catch (e) {
        dispatch({ type: POST_LIST_FAIL, payload: e.message })
    }
}

【问题讨论】:

    标签: javascript reactjs firebase google-cloud-firestore


    【解决方案1】:

    首先,所有异步函数都会返回一个 Promise,即使这不是您直接返回的。一旦您将函数标记为异步,它就会返回一个承诺,该承诺由您从它返回的数据实现。

    其次,如果您想执行查询并获得一组结果,则不应为此使用onSnapshot。这仅适用于随着时间的推移接收任意数量的文档更新的持久侦听器。如果你的函数是异步的,你只能从中返回一个对象,这与onSnapshot 不兼容。 onSnapshot 不返回可以等待的承诺。

    第三,您不能在map() lambda 函数中有效地使用 async/await。 map() 不会等待每个 await 完成,然后再转到数组中的下一个文档。

    如果您想从查询中获得一组结果,您应该使用get() 而不是onSnapshot()。这在documentation 中有说明。 get() 返回一个可以等待的承诺。

    您的解决方案的结构必须更像这样:

    const snap = await firestore.collection('comPosts').where('comId', '==', comId).get()
    const posts = []
    for (const doc of snap.docs) {
        const { userId } = doc.data()
        const { avatar, displayName } = (await firestore.collection('users').doc(userId).get()).data()
        posts.push({ ...doc.data(), avatar, displayName })
    }
    return posts
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 2018-10-16
      • 2018-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多