无法在 Dialogflow Fulfillment(在线编辑器)中从 Firestore 引入数据
Cannot bring data from Firestore in Dialogflow Fulfillment (In-line Editor)
我正在使用 Dialogflow 为 Google Assistant 构建一个 Action。一切正常,除了实现我的意图。
我正在使用 内联编辑器(由 Cloud Functions for Firebase 提供支持)来实现目的。我的函数本身运行 - 因为我可以从该函数向助手发送文本。
但出于某种原因,代码执行从未进入从 Firebase Firestore 上的 Collection
获取数据的函数 - 虽然它 是否执行前后命令。
这是我的 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(...)
块内执行任何操作。
我还尝试从 .then(...)
块中 return
ing 一个 Promise
,并使用第二个 .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
});
问题在于您正在执行异步操作(调用 get()
),但您并未 return 从 Intent Handler 本身获取 Promise。该库要求您 return 一个 Promise,以便它知道正在进行异步操作。
Return 中的 Promise then()
部分是不够的 - return 中的值不是处理程序,它只是 return 传递给下一个 then()
函数的值,或者(如果它是最后一个)作为整个 Promise 链的 return 值。
在您的原始代码中,只需 returning get().then().catch()
链即可完成此操作。你的第一行是这样的:
return db.collection("COLLECTION").orderBy("FIELD", "desc").get() // etc etc
在您的第二个示例中,then()
块中的 fetch
不是您认为的 fetch
,只会混淆问题。以这种方式构建,您需要 return 来自 let
作业的 fetch
。
你的第三个例子比较复杂。行
conv.add(getData());
从表面上看,它甚至似乎都行不通,因为它是 return 一个 Promise,但您不能向 conv
对象添加一个 Promise。您需要将该部分重写为
return getData()
.then( data => conv.add( data ) );
但这并没有说明 "Bye" 行的工作方式。如果你真的想要 "Bye" 在数据之后,你必须将它作为 then()
块的一部分。
简而言之,在处理异步数据时,需要
- 确保您了解 Promises 的工作原理并确保所有异步工作都使用 Promises 完成。
- 将所有数据添加到 Promise
then()
部分
- Return一个正确的承诺
我正在使用 Dialogflow 为 Google Assistant 构建一个 Action。一切正常,除了实现我的意图。
我正在使用 内联编辑器(由 Cloud Functions for Firebase 提供支持)来实现目的。我的函数本身运行 - 因为我可以从该函数向助手发送文本。
但出于某种原因,代码执行从未进入从 Firebase Firestore 上的 Collection
获取数据的函数 - 虽然它 是否执行前后命令。
这是我的 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(...)
块内执行任何操作。
我还尝试从 .then(...)
块中 return
ing 一个 Promise
,并使用第二个 .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
});
问题在于您正在执行异步操作(调用 get()
),但您并未 return 从 Intent Handler 本身获取 Promise。该库要求您 return 一个 Promise,以便它知道正在进行异步操作。
Return 中的 Promise then()
部分是不够的 - return 中的值不是处理程序,它只是 return 传递给下一个 then()
函数的值,或者(如果它是最后一个)作为整个 Promise 链的 return 值。
在您的原始代码中,只需 returning get().then().catch()
链即可完成此操作。你的第一行是这样的:
return db.collection("COLLECTION").orderBy("FIELD", "desc").get() // etc etc
在您的第二个示例中,then()
块中的 fetch
不是您认为的 fetch
,只会混淆问题。以这种方式构建,您需要 return 来自 let
作业的 fetch
。
你的第三个例子比较复杂。行
conv.add(getData());
从表面上看,它甚至似乎都行不通,因为它是 return 一个 Promise,但您不能向 conv
对象添加一个 Promise。您需要将该部分重写为
return getData()
.then( data => conv.add( data ) );
但这并没有说明 "Bye" 行的工作方式。如果你真的想要 "Bye" 在数据之后,你必须将它作为 then()
块的一部分。
简而言之,在处理异步数据时,需要
- 确保您了解 Promises 的工作原理并确保所有异步工作都使用 Promises 完成。
- 将所有数据添加到 Promise
then()
部分 - Return一个正确的承诺