我正在尝试使用Google Assistant在Dialogflow内联编辑器中从Firebase Realtime Database检索信息,但是由于某种原因,我返回了null
,Google Assistant回答了person1's Alex is null
我的参考文献定位不正确吗?我是第一次使用dialogflow和实时数据库。
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
var admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.cert({
projectId: ' ',
clientEmail: ' ',
privateKey: ' '
}),
databaseURL: 'https://*****.firebaseio.com'
});
process.env.DEBUG = 'dialogflow:debug';
// enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request,response)=>{
const agent = new WebhookClient({
request,
response
});
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function personFacts(agent) {
const personId = agent.parameters["personId"];
const personMeasurement = agent.parameters["personMeasurement"];
var db = admin.database();
var ref = db.ref(`person/${personId}/${personMeasurement}`);
return ref.once("value").then(snapshot=>{
var result = snapshot.val();
agent.add(`${personId}'s ${personMeasurement} is ${result}`);
}).catch(err=>{
agent.add('uh oh, something went wrong.');
console.error(err);
});
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('person', personFacts);
agent.handleRequest(intentMap);
});
根据建议,我将数字0、1、2更改为person1,person2,person3 对于实时数据库的引用几乎不需要帮助:
function personFacts(agent) {
const personId = agent.parameters["personId"];
const personMeasurement = agent.parameters["personMeasurement"];
const pperson = person[personId];
const result = pperson[personMeasurement];
var db = admin.database();
var ref = db.ref(`person/${personId}/${personMeasurement}`);
return ref.once("value")
.then( snapshot => {
var result = snapshot.val();
agent.add(`${personId}'s ${personMeasurement} is ${result}`);
})
.catch( err => {
agent.add('uh oh, something went wrong.');
console.error( err );
});
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('person', personFacts);
agent.handleRequest(intentMap);
});
答案 0 :(得分:0)
听起来您正在通过询问“ person 1”来询问信息,但是数据库中没有值“ person1”的键。在“人员”层次结构下有一个键“ 1”,也许这就是您想要的。
您有几种选择,具体取决于您要实际执行的操作。
您可以更改密钥以反映您的要求。因此,您可以仅使用“ person1”,“ person2”或“ person3”来代替按键使用“ 0”,“ 1”或“ 2”。您无需在Firebase数据库中使用数字。您可以使用但要引用数据。
另一种选择是将密钥保留在数据库中,并且当人员说“ person1”时,以某种方式将其映射到数据库中正确的密钥(即-“ 0”)。您可以编写代码来执行此操作-在这种情况下,您需要personId
参数的子字符串。所以也许像
let personKey = personId.substring(6);
,然后在参考路径中使用personKey
var ref = db.ref( `person/${personKey}/${personMeasurement}` );
但是,这些只是示例-如何执行取决于您要如何构造和访问数据。
重要的部分是了解Firebase数据库如何使您访问数据。数据存储在一个层次结构中,我们可以想到该层次结构中的每个节点都有一条路径。在您的示例中,您在顶部有一个名为“人”的节点。在该节点下,有几个只是数字的节点-一个名为“ 0”的节点就是一个例子。在“ 0”节点下,您有几个节点,其中一个名为“ Alex”。
您可以通过指定特定的“ Alex”节点的完整引用路径来对其进行引用。我们用“ /”分隔每个节点的名称。因此,指向此特定“ Alex”的完整参考路径为person/0/Alex
。要在此节点上获取值,我们可以构建一个ref
对象,然后使用once("value")
一次获取该值(而不是监听更改)。
由于其“ 0”和“ Alex”部分存储在变量中,因此我们需要构建一个包含这些值的字符串。一种简单的方法是在JavaScript中使用template literal或“反引号字符串”。在这种类型的字符串中,${}
中的所有内容都会被评估。因此${personKey}
的意思是将personKey
的值插入字符串。
所以这行
var ref = db.ref( `person/${personKey}/${personMeasurement}` );
表示“创建对数据库节点的引用,从“人”节点开始,然后在该节点下找到具有personKey
中值的节点,然后在该节点下找到具有{中值的节点{1}}”。
当然,您可以将personMeasurement
和personKey
替换为包含您要在节点层次结构中寻找的值的任何变量。您可以用其他方式构建此字符串,并使用其他工具构建引用。重要的一点是要了解引用是指向数据库中的某个点的,并且您需要先构建此引用,然后才能从该点获取引用。