我正在使用 Dialogflow 为Google Assistant构建操作。一切都可以,除了实现我的意图。
我正在使用 Inline Editor (由Cloud Functions for Firebase支持)来实现此目的。我的函数本身可以运行-因为我可以从函数向助手发送文本。
但是出于某种原因,代码执行从未进入 Firebase Firestore 上从我的Collection
获取数据的函数-尽管 确实 < / strong>在此之前和之后执行命令。
这是我的index.js
中的代码。
'use strict';
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
let db = admin.firestore();
const {dialogflow} = require('actions-on-google');
const app = dialogflow({debug: true});
app.intent('INTENT', (conv, {ENTITY}) => {
conv.add("Hello."); //THIS IS DISPLAYED
db.collection("COLLECTION").orderBy("FIELD", "desc").get().then(snapshot => {
conv.add("Hey!"); //THIS IS NOT DISPLAYED
snapshot.forEach(doc => {
conv.add("Hi?"); //NOR IS THIS
});
conv.add("Hmm..."); //NEITHER THIS
}).catch(error => {
conv.add('Error!'); //NOT EVEN THIS
});
conv.add("Bye."); //THIS IS DISPLAYED TOO
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
很显然,这表明执行从未真正进入db...
块,因此该功能甚至没有引发任何错误。
这是Firebase的日志。
Function execution started
Billing account not configured...
Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail
Request {...}
Headers {...}
Conversation {...}
Response {...}
Function execution took 1681 ms, finished with status code: 200
我知道firestore
函数异步获取数据,但是在那里
似乎即使在其.then(...)
块中也无法执行任何操作。
我还尝试return
从Promise
块中提取一个.then(...)
,并使用第二个.then(...)
-再次不起作用。
var fetch = db.collection("COLLECTION").orderBy("FIELD", "desc").get().then(snapshot => {
conv.add("Hey!"); //NOT DISPLAYED
var responseArr = [];
snapshot.forEach(doc => {
conv.add("Hi?"); //NOT DISPLAYED
responseArr.push(doc);
});
conv.add("Hmm..."); //NOT DISPLAYED
return Promise.resolve(responseArr);
}).then(fetch => {
conv.add("Here?"); //NOT DISPLAYED
}).catch(error => {
conv.add('Error!'); //NOT DISPLAYED
});
最后,我还尝试将firestore
函数放在单独的function
中,像这样。
function getData(){
return db.collection("COLLECTION").orderBy("FIELD", "desc").get().then(snapshot => {
snapshot.forEach(doc => {
...
});
return data; //Manipulated from above. 'data' can be a string.
}).catch(error => {
return error;
});
}
app.intent('INTENT', (conv, {ENTITY}) => {
conv.add("Hello."); //THIS IS DISPLAYED
conv.add(getData()); //THIS IS NOT DISPLAYED
conv.add("Bye."); //THIS IS DISPLAYED
});
答案 0 :(得分:2)
问题在于您正在执行异步操作(对get()
的调用),但没有从Intent Handler本身返回Promise。该库要求您返回一个Promise,以便它知道正在进行异步操作。
从内部{em> 返回一个then()
部分是不够的-这不会从处理程序中返回值,而只是返回传递给下一个{ {1}}函数或(如果是最后一个)作为整个Promise链的返回值。
在您的原始代码中,只需返回then()
链即可完成此操作。像这样的第一行:
get().then().catch()
在第二个示例中,return db.collection("COLLECTION").orderBy("FIELD", "desc").get() // etc etc
块中的fetch
不是您认为的then()
,只会使事情变得混乱。通过这种结构,您需要从fetch
分配中返回fetch
。
您的第三个示例更加复杂。线
let
从表面上看,甚至看起来都不可行,因为它返回了Promise,但是您不能向conv.add(getData());
对象添加承诺。您需要将该部分重写为
conv
但是,这并没有解决“再见”行的工作方式。如果您确实想在数据后添加“ Bye”,则必须将其作为return getData()
.then( data => conv.add( data ) );
块的一部分。
简而言之,在处理异步数据时,您需要
then()
部分