【问题标题】:Get a list of firestore documents from array of id's从 id 数组中获取 firestore 文档列表
【发布时间】:2020-09-07 19:17:40
【问题描述】:

我有一个 firestore 集合,他的值之一是文档 ID 数组。 我需要检索所有集合项目以及存储在数组 id 中的所有文档。 这是我收藏的结构

我的代码:

export const getFeaturedMixes = functions.https.onRequest((request, response) => {
    let result:any[] = []
    featuredMixes.get().then(mixesSnap => {

        mixesSnap.forEach(doc => {
            let docId = doc.id
            let ids = doc.data().tracks

            let resultTracks:any[] = []
            ids.forEach(id => {
                let t = tracksCollection.doc(id.track_id).get()
                resultTracks.push({'id' : id.track_id, 'data': t})
            })
            result.push({'id':docId, 'tracks': resultTracks})
        })
        return result
    })
    .then(results => {
        response.status(200).send(results)
    }).catch(function(error) {
        response.status(400).send(error)
    })
});

我收到了这样的回复:

{
        "id": "Xm4TJAnKcXJAuaZr",
        "tracks": [
            {
                "id": "FG3xXfldeJBbl8PY6",
                "data": {
                    "domain": {
                        "domain": null,
                        "_events": {},
                        "_eventsCount": 1,
                        "members": []
                    }
                }
            },
            {
                "id": "ONRfLIh89amSdcLt",
                "data": {
                    "domain": {
                        "domain": null,
                        "_events": {},
                        "_eventsCount": 1,
                        "members": []
                    }
                }
            }
    ]
}

响应不包含文档数据

【问题讨论】:

    标签: node.js typescript firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

    get() 方法是异步的,并返回一个 Promise。因此,您不能执行以下操作:

     ids.forEach(id => {
          let t = tracksCollection.doc(id.track_id).get()
          resultTracks.push({'id' : id.track_id, 'data': t})
     })
    

    您需要等待get() 方法返回的Promise 解析,才能使用t(即DocumentSnapshot)。

    为此,由于您要并行获取多个文档,因此需要使用Promise.all()

    以下应该可以解决问题。请注意,它没有经过测试,并且您仍然可以完成代码的简单部分,请参阅最后的 cmets。如果您在完成时遇到问题,请将您的新代码添加到您的问题中。

    export const getFeaturedMixes = functions.https.onRequest((request, response) => {
        let result: any[] = []
    
        const docIds = [];
    
        featuredMixes.get()
            .then(mixesSnap => {
    
    
                mixesSnap.forEach(doc => {
                    let docId = doc.id
                    let ids = doc.data().tracks
    
                    const promises = []
    
                    ids.forEach(id => {
                        docIds.push(docId);
                        promises.push(tracksCollection.doc(id.track_id).get())
                    })
    
                })
    
                return Promise.all(promises)
            })
            .then(documentSnapshotArray => {
    
                // Here documentSnapshotArray is an array of DocumentSnapshot corresponding to
                // the data of all the documents with track_ids
    
                // In addition, docIds is an array of all the ids of the FeaturedMixes document
    
                // IMPORTANT: These two arrays have the same length and are ordered the same way
    
                //I let you write the code to generate the object you want to send back to the client: loop over those two arrays in parallel and build your object
    
    
                let resultTracks: any[] = []
    
                documentSnapshotArray.forEach((doc, idx) => {
                    // .....
                    // Use the idx index to read the two Arrays in parallel
    
                })
    
                response.status(200).send(results)
    
            })
            .catch(function (error) {
                response.status(400).send(error)
            })
    });
    

    【讨论】:

      【解决方案2】:

      谢谢雷诺塔内克!!你的回答真的很有希望,功能已经在工作,但是我想返回 Promise.all(primises) 一些对象,其中包含 mix 和他的曲目,因为现在很难构建then 函数中的新对象, 这是我的最终功能

          const mixIDs: any[] = [];
          const mixes:any[] =[]
      
          featuredMixes.get()
              .then(mixesSnap => {
                  const promises:any[] = []
      
                  mixesSnap.forEach(doc => {
                      let mixId = doc.id
                      let mix = createMix(doc)
                      mixes.push(mix)
      
                      doc.data().tracks.forEach(track => {
                          let promise = tracksCollection.doc(track.track_id).get()
                          promises.push(promise)
                          mixIDs.push(mixId)
                      })
                  })
                  return Promise.all(promises)
              })
              .then(tracksSnapshot => {
      
                  let buildedTracks = tracksSnapshot.map((doc, idx) => {
                      let mId = mixIDs[idx]
                      return createTrack(doc, mId)
                  })
      
                  let result = mixes.map(mix => {
                      let filterTracks = buildedTracks.filter(x => x.mix_id === mix.doc_id)
                      return Object.assign(mix, {'tracks': filterTracks})
                  })
                  response.status(200).send(result)
              })
              .catch(function (error) {
                  response.status(400).send(error)
              })
      })
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 2018-04-04
      • 2021-01-28
      • 2020-12-03
      • 1970-01-01
      相关资源
      最近更新 更多