Firebase + DialogFlow - 实时数据库 - 云函数 return 仅在第二次请求后查询结果
Firebase + DialogFlow - Realtime database- Cloud function return query result only after second request
我正在编写一个简单的 Google 操作,它将读取 Firebase 实时数据库,并且 return 会产生响应。我的问题是,查询结果仅在至少 2 次尝试后才被传回以响应 DialogFlow。
下面的屏幕截图显示了模拟器中的最终结果
First query screenshot
响应的第一行是 return 从 Cloud Function 编辑的,包含通过“上下文”传递的值。此响应中没有第二行。
下面是第二次发送完全相同的请求后的结果屏幕。
Second query screenshot
第一行和之前一样,但是这次我也得到了第二行,其中包含查询结果数据。
看起来我的代码正在“工作”(我从数据库中获取了正确的数据),但出于某种原因,它只有在我快速连续触发它至少 2 次时才有效。
下面是处理此请求的代码片段:
function googleAssistantHandler(agent) {
let conv = agent.conv();
let outCommandContext = agent.getContext('outcommand');
let outCharacterContext = agent.getContext('outcharacter');
let character = outCharacterContext.parameters.character;
let command = outCommandContext.parameters.command;
agent.add('<prosody rate="140%" pitch="0.4">' + character +' '+ command +'</prosody>');
var movesRef = admin.database().ref('characters/'+character.toLowerCase()+'/moves/');
movesRef.limitToFirst(1).orderByChild("notation")
.equalTo(command.toString()).on("child_added",function(snapshot){
agent.add(`record number is ` + snapshot.key);
});
}
我试过使用 once() 而不是 on() (因为它对我来说更有意义......我不需要监听数据库的变化,我只想检索数据一次)- 但是,我无法让它工作。
你们能帮我理解 为什么 我的查询 return 的结果只在第二次触发后才出现吗?
谢谢!
您正在使用回调方法从数据库中获取数据,因此无法保证它会在您的函数被 returned 之前调用。要解决此问题,您需要在函数中使用 Promise 和 return 那个 Promise,这样函数的最后几行将如下所示
return movesRef.limitToFirst(1).orderByChild("notation")
.equalTo(command.toString()).on("child_added").then(snapshot= > {
agent.add(`record number is ` + snapshot.key);
});
您在使用数据库时需要始终使用 promises。此外,您看到的第一个响应可能是因为失败的函数超时。如果您在 firebase 中看到控制台日志,您可能会看到错误。还要检查您的默认响应,如果它包含 User said $name
或类似内容的文本,那么这就是导致第一次尝试出现问题的原因。
如果您仍然无法正常工作,请尝试记录返回的数据,并在此处 post 您的日志。
我正在编写一个简单的 Google 操作,它将读取 Firebase 实时数据库,并且 return 会产生响应。我的问题是,查询结果仅在至少 2 次尝试后才被传回以响应 DialogFlow。 下面的屏幕截图显示了模拟器中的最终结果 First query screenshot 响应的第一行是 return 从 Cloud Function 编辑的,包含通过“上下文”传递的值。此响应中没有第二行。
下面是第二次发送完全相同的请求后的结果屏幕。 Second query screenshot 第一行和之前一样,但是这次我也得到了第二行,其中包含查询结果数据。
看起来我的代码正在“工作”(我从数据库中获取了正确的数据),但出于某种原因,它只有在我快速连续触发它至少 2 次时才有效。
下面是处理此请求的代码片段:
function googleAssistantHandler(agent) {
let conv = agent.conv();
let outCommandContext = agent.getContext('outcommand');
let outCharacterContext = agent.getContext('outcharacter');
let character = outCharacterContext.parameters.character;
let command = outCommandContext.parameters.command;
agent.add('<prosody rate="140%" pitch="0.4">' + character +' '+ command +'</prosody>');
var movesRef = admin.database().ref('characters/'+character.toLowerCase()+'/moves/');
movesRef.limitToFirst(1).orderByChild("notation")
.equalTo(command.toString()).on("child_added",function(snapshot){
agent.add(`record number is ` + snapshot.key);
});
}
我试过使用 once() 而不是 on() (因为它对我来说更有意义......我不需要监听数据库的变化,我只想检索数据一次)- 但是,我无法让它工作。
你们能帮我理解 为什么 我的查询 return 的结果只在第二次触发后才出现吗? 谢谢!
您正在使用回调方法从数据库中获取数据,因此无法保证它会在您的函数被 returned 之前调用。要解决此问题,您需要在函数中使用 Promise 和 return 那个 Promise,这样函数的最后几行将如下所示
return movesRef.limitToFirst(1).orderByChild("notation")
.equalTo(command.toString()).on("child_added").then(snapshot= > {
agent.add(`record number is ` + snapshot.key);
});
您在使用数据库时需要始终使用 promises。此外,您看到的第一个响应可能是因为失败的函数超时。如果您在 firebase 中看到控制台日志,您可能会看到错误。还要检查您的默认响应,如果它包含 User said $name
或类似内容的文本,那么这就是导致第一次尝试出现问题的原因。
如果您仍然无法正常工作,请尝试记录返回的数据,并在此处 post 您的日志。