【问题标题】:Why is Firebase Query [ ] despite async/await?为什么 Firebase Query [ ] 尽管 async/await?
【发布时间】:2021-10-09 14:31:39
【问题描述】:

我仍在努力了解如何从 Firestore 查询中提取值并将它们放入全局变量中。我(现在)理解异步性质意味着代码不是按照编写的顺序执行的。但是,尽管async 函数内部有await 关键字,为什么user 在以下代码块中仍未定义?我了解(基于this questionawait 应仅应用于get(),否则可能没有要迭代的值。

我的问题与this 类似,但我遇到了与评论相同的问题,并且看起来该问题从未标记为已回答。它也类似于this,但将所有的gets 推送到一个Promise,然后解决该promise 仍然没有将数据分配给一个变量。它只是打印了一个空数组。

我可以打印变量,所以我想我的问题是关于赋值。该函数是DialogFlowIntent 的处理程序。我强烈希望在对 db 的调用之外提供可用的数据。在对 firestore 的调用中添加到代理响应并不总是将文本添加到代理,所以我想避免这种情况。

async function loginHandler(agent){     
     username = agent.parameters.username.name;      
     password = agent.parameters.password;

        const user = await db.collection("users")
                    .where("name","==",username)
                     .where("password","==",password)
                     .limit(1)
                     .get()
                     .then(querySnapshot =>{
                        querySnapshot.forEach(docSnapShot =>{
                            return docSnapShot.data();
                            //console.log.(docSnapShot.data()); //prints correct contents, so error is in programming logic
                            agent.add("Response"); // Would prefer to avoid this, but could refactor if I am fundamentally misunderstanding how to access Firebase data
                        })
                     })
                     .catch(error => console.log);
                                 

        console.log(user);      
       console.log("bort");  
}

Firestore 的图片以证明确实存在正确的数据:

【问题讨论】:

    标签: javascript firebase asynchronous google-cloud-firestore dialogflow-es-fulfillment


    【解决方案1】:

    您也许可以拆分代码。首先从数据库返回数据,然后map 覆盖数据以提取详细信息,然后然后将该结果分配给user 变量。

    async function loginHandler(agent) {
    
      username = agent.parameters.username.name;
      password = agent.parameters.password;
    
      // `await` the promise and assign it to
      // `querySnapshot`
      const querySnapshot = await db.collection('users')
        .where('name', '==', username)
        .where('password', '==', password)
        .limit(1)
        .get()
        .catch(error => console.log);
      
      const user = querySnapshot.docs.map(docSnapShot => {
        agent.add('Response');
        return docSnapShot.data();
      });
    
      console.log(user);
    
    }

    【讨论】:

    • 谢谢。我收到错误TypeError: data.map is not a function。我在获取后删除了;
    • data 的值是多少?它是一个对象吗? @mac389
    • {"username":"Bob", "password":"123123"} 都是字符串。
    • querySnapshot.forEach 在您的代码中在该上下文中没有意义,因为querySnapshot 也将是一个对象。它们在功能上是相同的。
    • 我通过在const user 的定义中将querySnapshot.map 替换为querySnapshot.docs.map 来使其工作。
    【解决方案2】:

    forEach 迭代结果但不返回任何内容,因此您的 return 内部没有做您期望的事情(forEach 返回 void 所以您将快照返回给函数即返回void)。您可以创建一个局部变量来保存您迭代的结果,然后将其返回:

    const user = await db.collection("users")
                        .where("name","==",username)
                        .where("password","==",password)
                        .limit(1)
                        .get()
                        .then(querySnapshot =>{
                            // Set up an empty array to return later
                            let data = []
                            querySnapshot.forEach(docSnapShot =>{
                                // Add each snapshot's data object to the array
                                data = [...data, ...docSnapShot.data()]
                            })
                            // Return `data` which will populate `user`
                            return data
                         })
                         .catch(error => console.log);
    

    【讨论】:

    • 谢谢。当我使用这个方法时console.log(user)undefined 如果我有两个console.log 语句,否则它打印[Function: log],这表明get 正在抛出错误?
    【解决方案3】:

    你检查过正确答案是什么吗?

    请澄清您是指标题中所说的undefined,还是正文中所说的empty array

    您的代码在我看来是正确的。我不希望console.log(user) 的输出是undefined。但是,空列表[ ] 将是一个完全合理的答案。

    也许该集合中没有人使用该用户名和密码?

    您是否尝试过删除用户名和密码相等的条件?如果它不完全为空,那应该会为您提供集合的元素。

    【讨论】:

    • 我的意思是[ ],一个空数组。我已经更新了标题。但是,我在一个测试集合上运行它,我确信这个用户名/密码组合存在(并在console 语句指示的位置返回。)
    猜你喜欢
    • 2017-10-26
    • 2020-01-24
    • 2021-11-13
    • 2016-05-12
    • 2019-12-18
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    相关资源
    最近更新 更多