简体   繁体   English

Firebase Firestore.where().get() 快照的“forEach”问题

[英]Trouble with “forEach” with Firebase Firestore .where() .get() Snapshots

I can only give an example of my code, since my real code is too big.我只能举一个我的代码示例,因为我的真实代码太大了。 I'm working with Firebase Cloud Functions and Firebase Firestore.我正在使用 Firebase Cloud Functions 和 Firebase Firestore。

First I define a returnData dictionary (within my Firebase Cloud Function):首先,我定义了一个returnData字典(在我的 Firebase 云函数中):

let returnData = {};

Then I get() "snapshots" of my db :然后我get()我的db的“快照”:

const db = admin.firestore();
const snapshotUsers = await db
      .collection("users")
      .where("followers", "array-contains", exampleId)
      .get();

Then, I'm trying to populate the returnData dictionary:然后,我试图填充returnData字典:

snapshotUsers.forEach(async (docUsers) => {
    await db
    .collection("users")
    .doc(docUsers.id)
    .collection("profileProjects")
    .listDocuments()
    .then(async (documentRefsProjects) => {
        if (!(Object.keys(documentRefsProjects).length === 0)) {
            return await db.getAll(...documentRefsProjects);
        }
    })
    .then(async (documentSnapshotsProjects) => {
        if (!!documentSnapshotsProject) {
            for (let documentSnapshotProject of documentSnapshotsProjects) {
                if (documentSnapshotProject.exists) {
                    // ----------- Populate here ----------- 
                    returnData = {
                        ...returnData,
                        [documentSnapshotProject.id]: {
                            followers: docUsers.data().followers,
                        }
                    };
                    // -------------------------------------- 
                }
            }
        }
    })
});
// Send response when forEach is done with returnData
res.status(201).send({ returnData: returnData });

Problem is : once it successfully populates returnData , it then throws that data away and res.status(201).send({ returnData: returnData });问题是:一旦成功填充returnData ,它就会丢弃该数据并res.status(201).send({ returnData: returnData }); returns the initial empty dictionary返回初始的空字典

I understand that: "forEach() executes the callback function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable" , but I seems like I have no other option than to use forEach for firestore , so I'm stuck.我明白: “forEach() 为每个数组元素执行一次回调 function;与 map() 或 reduce() 不同,它总是返回未定义的值并且不可链接” ,但我似乎别无选择,只能 使用forEach for firestore ,所以我被卡住了。

I tried using the map() function instead, but Firestore returns TypeError: snapshotUsers.map is not a function .尝试使用map() function 代替,但 Firestore 返回TypeError: snapshotUsers.map is not a function

I even tried doing a manual for...in and for...of loop, but those also gave me errors when I would try to call id on docUsers :我什至尝试过手动 for...in 和 for...of 循环,但是当我尝试在docUsers上调用id时,这些也给了我错误:

for (let docUsers of snapshotUsers) {
    await db
        .collection("users")
        .doc(snapshotUsers[docUsers].id) // <---- error'd here

I'm having a real tough time here since the only way I can test this is deploying the Firebase Cloud Function every time.我在这里过得很艰难,因为我可以测试的唯一方法是每次都部署 Firebase Cloud Function。

I wondering if anyone can help me out here.我想知道是否有人可以在这里帮助我。 Any advice or solution helps.任何建议或解决方案都会有所帮助。

I'm having a real tough time here since the only way I can test this is deploying the Firebase Cloud Function every time.我在这里过得很艰难,因为我可以测试的唯一方法是每次都部署 Firebase Cloud Function。

check it: https://firebase.google.com/docs/hosting/test-preview-deploy检查它: https://firebase.google.com/docs/hosting/test-preview-deploy

I used to work with:我曾经与:

firebase serve --only functions

And it just work fine.它工作正常。

For your problem...对于你的问题...

Your foreach is ending before your returnData is populated.你的 foreach 在你的 returnData 被填充之前就结束了。 Foreach has one argument that show the current data index in your array. Foreach 有一个参数可以显示数组中的当前数据索引。

So, in your success callback, you can check if it is the last array's data then just send your response.因此,在您的成功回调中,您可以检查它是否是最后一个数组的数据,然后发送您的响应。

Something like this:像这样的东西:

let returnData;
xpto.forEach((data,index)=>{
    db.then(()=>{
        //populates your returnData
        if(index === xpto.lenght-1) res.status(201).send({ returnData })
    })
})

Edit with askers experience:用提问者的经验编辑:

for some reason didn't work with the snapshots, I had to initialize an index outside the forEach and increment it within the.then() function.由于某种原因无法使用快照,我不得不在 forEach 之外初始化一个索引并在.then() function 内增加它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM