从实时数据库获取 json 数据到 Dialogflow 内联编辑器(google 助手)
get json data from realtime database to Dialogflow inline editor (google assistant)
这里是编程初学者,空闲时间我正在做一个与 Google Assistant 相关的项目,这是我第一次使用 Firebase 实时数据库,但不知道如何使用要从那里获取数据,下面的代码位于 Dialogflow 的内联编辑器中,其中 category1 2 和 3 其中是有学分的学生。我做了一些修改,将这三个(类别 1 2 和 3)放在下面的数据库图片中,我想从代码中删除这三个类别并用实时数据库中的类别替换它。
因为这是我第一次使用该数据库,所以我不知道如何使用 nodejs 从那里获取数据。
function categoryac(agent) {
const categories = {
category1: {"Alex" : 25, "Jennifer" : 45, "Justin" : 35, "Peter" : 89},
category2: {"Alex" : 95, "Jennifer" : 75, "Justin" : 85, "Peter" : 59},
category3: {"Alex" : 67, "Jennifer" : 55, "Justin" : 45, "Peter" : 15},
};
const categoried = agent.parameters["categoried"];
const categoryAmount = agent.parameters["categoryAmount"];
const category = category[categoried];
const aggregate = category[categoryAmount];
agent.add(`${categoried}'s ${categoryAmount} is ${aggregate}`);
}
let intentMap = new Map();
intentMap.set('category', categoryac);
agent.handleRequest(intentMap);
});
更新
我使用了下面的代码,如下所示:
function categoryac( agent ){
const categoried = agent.parameters["categoried"];
const categoryAmount = agent.parameters["categoryAmount"];
var admin = require( 'firebase-admin' );
admin.initializeApp( {
credential: admin.credential.cert( {
projectId: ' ',
clientEmail: ' ',
privateKey: ' '
} ),
dblink: 'www.*****.*****.com'
} );
var thing = admin.database();
var relating= thing.ref( `category/${categoried}/${categoryAmount}` );
return relating.once( "value" ).then( snapshot =>{
var aggregate = snapshot.value();
agent.add( `${categoried}'s ${categoryAmount} is ${aggregate}` );
} )
.catch( fail =>{
agent.add( 'uh oh, something went wrong.' );
console.error( fail );
} );
}
let intentMap = new Map();
intentMap.set( 'category', categoryac );
agent.handleRequest( intentMap );
} );
收到错误消息:'MalformedResponse
由于语音响应为空,无法将 Dialogflow 响应解析为 AppResponse。”日志错误:
{
insertId: "v*****2"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "JSON_RESPONSE_VALIDATION"
}
logName: "projects/****/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-01-07T14:45:29.274840871Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "******"
version_id: ""
}
type: "assistant_action"
}
severity: "ERROR"
textPayload: "MalformedResponse: Failed to parse Dialogflow response into AppResponse because of empty speech response"
timestamp: "2019-01-07T14:45:29.266062732Z"
trace: "projects/383182941858/traces/ABwppHFK_PehMj1XEs_Arng9VL7_zShy-EWvoziK0Ro6v74TaduNG1cJaRMnGAZMoLZhtILdG2hEBkDvJQ"
}
这是日志中的错误:
Error: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name.
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:119:28)
at FirebaseNamespaceInternals.initializeApp (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:68:23)
at FirebaseNamespace.initializeApp (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:362:30)
at categoryac (/user_code/index.js:34:11)
at WebhookClient.handleRequest (/user_code/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:303:44)
at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/user_code/index.js:91:9)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:57:9)
您需要学习几件事。
首先是如何add the Firebase Admin SDK到你的项目中。
您还需要了解如何 retrieve the data 使用该库。 Firebase 使用基于引用路径的方法来获取数据,因此您需要确保正确构建路径。
最后,由于您是在执行处理程序中执行此操作,并且正在进行异步调用,因此您需要确保 return 一个 Promise。幸运的是,获取数据还涉及 return 一个 Promise,因此您可以 return 这个 Promise。
部分代码可能看起来像这样(未经测试):
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 );
});
}
如您所述,您需要使用密钥初始化 Firebase 管理库,以便您通过服务帐户进行访问。您可以 generate the key 并下载它,然后指向您保存它的文件夹。 (看起来你刚刚内联了信息,这也有效。)
"Malformed Response"错误表示没有设置响应。这可能是由多种原因造成的,但通常意味着您的程序崩溃或由于某种原因无法调用 agent.add()
。请查阅您的操作日志 运行 了解更多信息。 (如果您使用的是 Dialogflow 内联编辑器,您可以通过转至 https://console.firebase.google.com/、选择您的项目、选择左侧的 "Functions" 选项卡并选择 "logs" 选项卡来访问日志.)
根据代码和错误信息更新
如错误消息所示,您多次调用 admin.initializeApp()
。这应该只在函数首次配置时完成,而不是在每次调用函数时完成。一次初始化一次 - 可以多次使用。
在您的情况下,这可以通过将导入 firebase-admin 的 require
和对 admin.initializeApp()
的调用移出 personFacts()
函数并将它们放在更接近顶部 - 可能就在其他 require()
调用之后。
这里是编程初学者,空闲时间我正在做一个与 Google Assistant 相关的项目,这是我第一次使用 Firebase 实时数据库,但不知道如何使用要从那里获取数据,下面的代码位于 Dialogflow 的内联编辑器中,其中 category1 2 和 3 其中是有学分的学生。我做了一些修改,将这三个(类别 1 2 和 3)放在下面的数据库图片中,我想从代码中删除这三个类别并用实时数据库中的类别替换它。
因为这是我第一次使用该数据库,所以我不知道如何使用 nodejs 从那里获取数据。
function categoryac(agent) {
const categories = {
category1: {"Alex" : 25, "Jennifer" : 45, "Justin" : 35, "Peter" : 89},
category2: {"Alex" : 95, "Jennifer" : 75, "Justin" : 85, "Peter" : 59},
category3: {"Alex" : 67, "Jennifer" : 55, "Justin" : 45, "Peter" : 15},
};
const categoried = agent.parameters["categoried"];
const categoryAmount = agent.parameters["categoryAmount"];
const category = category[categoried];
const aggregate = category[categoryAmount];
agent.add(`${categoried}'s ${categoryAmount} is ${aggregate}`);
}
let intentMap = new Map();
intentMap.set('category', categoryac);
agent.handleRequest(intentMap);
});
更新 我使用了下面的代码,如下所示:
function categoryac( agent ){
const categoried = agent.parameters["categoried"];
const categoryAmount = agent.parameters["categoryAmount"];
var admin = require( 'firebase-admin' );
admin.initializeApp( {
credential: admin.credential.cert( {
projectId: ' ',
clientEmail: ' ',
privateKey: ' '
} ),
dblink: 'www.*****.*****.com'
} );
var thing = admin.database();
var relating= thing.ref( `category/${categoried}/${categoryAmount}` );
return relating.once( "value" ).then( snapshot =>{
var aggregate = snapshot.value();
agent.add( `${categoried}'s ${categoryAmount} is ${aggregate}` );
} )
.catch( fail =>{
agent.add( 'uh oh, something went wrong.' );
console.error( fail );
} );
}
let intentMap = new Map();
intentMap.set( 'category', categoryac );
agent.handleRequest( intentMap );
} );
{
insertId: "v*****2"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "JSON_RESPONSE_VALIDATION"
}
logName: "projects/****/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2019-01-07T14:45:29.274840871Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "******"
version_id: ""
}
type: "assistant_action"
}
severity: "ERROR"
textPayload: "MalformedResponse: Failed to parse Dialogflow response into AppResponse because of empty speech response"
timestamp: "2019-01-07T14:45:29.266062732Z"
trace: "projects/383182941858/traces/ABwppHFK_PehMj1XEs_Arng9VL7_zShy-EWvoziK0Ro6v74TaduNG1cJaRMnGAZMoLZhtILdG2hEBkDvJQ"
}
这是日志中的错误:
Error: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name.
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:119:28)
at FirebaseNamespaceInternals.initializeApp (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:68:23)
at FirebaseNamespace.initializeApp (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:362:30)
at categoryac (/user_code/index.js:34:11)
at WebhookClient.handleRequest (/user_code/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:303:44)
at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/user_code/index.js:91:9)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:57:9)
您需要学习几件事。
首先是如何add the Firebase Admin SDK到你的项目中。
您还需要了解如何 retrieve the data 使用该库。 Firebase 使用基于引用路径的方法来获取数据,因此您需要确保正确构建路径。
最后,由于您是在执行处理程序中执行此操作,并且正在进行异步调用,因此您需要确保 return 一个 Promise。幸运的是,获取数据还涉及 return 一个 Promise,因此您可以 return 这个 Promise。
部分代码可能看起来像这样(未经测试):
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 );
});
}
如您所述,您需要使用密钥初始化 Firebase 管理库,以便您通过服务帐户进行访问。您可以 generate the key 并下载它,然后指向您保存它的文件夹。 (看起来你刚刚内联了信息,这也有效。)
"Malformed Response"错误表示没有设置响应。这可能是由多种原因造成的,但通常意味着您的程序崩溃或由于某种原因无法调用 agent.add()
。请查阅您的操作日志 运行 了解更多信息。 (如果您使用的是 Dialogflow 内联编辑器,您可以通过转至 https://console.firebase.google.com/、选择您的项目、选择左侧的 "Functions" 选项卡并选择 "logs" 选项卡来访问日志.)
根据代码和错误信息更新
如错误消息所示,您多次调用 admin.initializeApp()
。这应该只在函数首次配置时完成,而不是在每次调用函数时完成。一次初始化一次 - 可以多次使用。
在您的情况下,这可以通过将导入 firebase-admin 的 require
和对 admin.initializeApp()
的调用移出 personFacts()
函数并将它们放在更接近顶部 - 可能就在其他 require()
调用之后。