Firestore 查询具有多个值的循环

Sha*_*a-1 4 javascript firebase google-cloud-functions google-cloud-firestore

我正在尝试使用保存在字符串中的数据来检索多个 Firestore 文档。这个想法是,对于数组中的每个值,我会使用 Firestore 查询来检索与该查询匹配的文档并将其推送到另一个数组。我在实现这一目标时遇到了一些问题。到目前为止,我已经尝试过:

exports.findMultipleItems = functions.https.onRequest((request, response) => {
    var list = ["item1", "item2", "item3", "item4"];

    var outputList = [];

    for (var i = 0; i < list.length; i++) {
        console.log("Current item: " + list[i]);
        let queryRef = db.collection("items").where('listedItems', 'array-contains', list[i]).get()
            .then(snapshot => {
                if (snapshot.empty) {
                    console.log('No matching documents.');
                }

                snapshot.forEach(doc => {
                    outputList.push(doc.data());
                });
                return;
            })
            .catch(err => {
                console.log('Error getting documents', err);
            });
    }

    response.send(JSON.stringify(outputList));

});
Run Code Online (Sandbox Code Playgroud)

我不完全确定,但我认为问题之一是 for 循环在查询有机会完成之前完成。

Ps - 这是使用 Admin SDK 通过 Cloud Functions 运行的。

Dou*_*son 7

queryRef实际上不是参考。这是在您的 get/then/catch 完成后解决的承诺。您需要使用这些承诺来确定它们何时全部完成。只有在它们全部完成后才会填充数组,只有这样才能安全地使用该数组发送响应。

将所有的 promise 收集到一个数组中,并使用 Promise.all() 获得一个新的 promise,在它们全部完成后解析:

exports.findMultipleItems = functions.https.onRequest((request, response) => {
    var list = ["item1", "item2", "item3", "item4"];

    var outputList = [];
    const promises = [];

    for (var i = 0; i < list.length; i++) {
        console.log("Current item: " + list[i]);
        let promise = db.collection("items").where('listedItems', 'array-contains', list[i]).get()
            .then(snapshot => {
                if (snapshot.empty) {
                    console.log('No matching documents.');
                }

                snapshot.forEach(doc => {
                    outputList.push(doc.data());
                });
                return;
            })
            .catch(err => {
                console.log('Error getting documents', err);
            });
        promises.push(promise);
    }

    Promise.all(promises).then(() => {
        response.send(JSON.stringify(outputList));
    }
    .catch(err => {
        response.status(500);
    })

});
Run Code Online (Sandbox Code Playgroud)

您可能希望使用这些教程来更好地了解如何在 Cloud Functions 中处理 promise:

https://firebase.google.com/docs/functions/video-series/