为什么 Firebase 查询 [ ] 尽管 async/await?
Why is Firebase Query [ ] despite async/await?
我仍在努力理解如何从 Firestore 查询中提取值并将它们放入全局变量中。我(现在)明白异步性质意味着代码不会按照编写的顺序执行。但是,尽管 async
函数中有 await
关键字,但为什么 user
在以下代码块中仍然未定义?我理解(基于 )await
应该只应用到 get()
,否则可能没有要迭代的值。
我的问题类似于this, but I run into the same issue as the comment and it looks like the question was never marked as answered. It is also similar to this,但是将所有内容推送到一个Promise,然后解决该promise 仍然没有将数据分配给变量。它只是打印了一个空数组。
我可以打印变量,所以我想我的问题是关于赋值的。此函数是 DialogFlow
中 Intent
的处理程序。我强烈希望在调用数据库之外获得数据。在调用 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 图片:
你检查过正确答案是什么了吗?
请说明您是指标题中的undefined
,还是文中所说的empty array
。
我认为你的代码是正确的。我不希望 console.log(user)
的输出是 undefined
。但是,空列表 [ ]
将是一个完全合理的答案。
也许 collection 中没有人使用该用户名和密码?
您是否尝试过删除用户名和密码相等的条件?如果 collection 不完全为空,那应该会给你一个元素。
forEach
迭代结果但不 return 任何东西,所以你的 return
里面没有做你期望的事情(forEach
returns void
所以你正在 return 快照到一个正在 returning void
的函数。您可以创建一个局部变量来保存您迭代的结果,然后 return 那:
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);
您或许可以拆分代码。 Return 首先从数据库中获取数据,然后 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);
}
我仍在努力理解如何从 Firestore 查询中提取值并将它们放入全局变量中。我(现在)明白异步性质意味着代码不会按照编写的顺序执行。但是,尽管 async
函数中有 await
关键字,但为什么 user
在以下代码块中仍然未定义?我理解(基于 await
应该只应用到 get()
,否则可能没有要迭代的值。
我的问题类似于this, but I run into the same issue as the comment and it looks like the question was never marked as answered. It is also similar to this,但是将所有内容推送到一个Promise,然后解决该promise 仍然没有将数据分配给变量。它只是打印了一个空数组。
我可以打印变量,所以我想我的问题是关于赋值的。此函数是 DialogFlow
中 Intent
的处理程序。我强烈希望在调用数据库之外获得数据。在调用 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 图片:
你检查过正确答案是什么了吗?
请说明您是指标题中的undefined
,还是文中所说的empty array
。
我认为你的代码是正确的。我不希望 console.log(user)
的输出是 undefined
。但是,空列表 [ ]
将是一个完全合理的答案。
也许 collection 中没有人使用该用户名和密码?
您是否尝试过删除用户名和密码相等的条件?如果 collection 不完全为空,那应该会给你一个元素。
forEach
迭代结果但不 return 任何东西,所以你的 return
里面没有做你期望的事情(forEach
returns void
所以你正在 return 快照到一个正在 returning void
的函数。您可以创建一个局部变量来保存您迭代的结果,然后 return 那:
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);
您或许可以拆分代码。 Return 首先从数据库中获取数据,然后 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);
}