我得到了一个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": []
}
}
}
]
}
response doesn't contains document data
的结构。get()
方法是异步的,并返回一个 Promise。因此你不能做这样的事情。
ids.forEach(id => {
let t = tracksCollection.doc(id.track_id).get()
resultTracks.push({'id' : id.track_id, 'data': t})
})
你需要等待Promise方法返回的是... get()
方法解析,以便能够使用 t
(这是一个 DocumentSnapshot
).
为此,由于你想并行获取多个文档,你需要使用 Promise.all()
.
下面应该可以做到。需要注意的是,它没有经过测试,还有一部分简单的代码需要你来完成,请看最后的注释。如果你在定稿时遇到一些问题,请把你的新代码补充到你的问题中。
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)
})
});
谢谢 Renaud Tarnec!!!!真的很希望你的答案,函数已经在工作了,但是我想返回Promise.all(primises)一些持有Promise.all(primises)的对象。混合 与他的轨道,因为现在很难在然后的函数中建立新的对象,这是我的最终函数
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)
})
})