Firebase dialogflow聊天机器人如何转到firestore数据库并返回支持相关问题?

Firebase dialogflow聊天机器人如何转到firestore数据库并返回支持相关问题?,firebase,artificial-intelligence,dialogflow-es,chatbot,Firebase,Artificial Intelligence,Dialogflow Es,Chatbot,我正在为我的“dialogflow”聊天机器人使用“firestore”数据库,我已经为一家在线杂货店创建了这个聊天机器人。问题是:我希望我的聊天机器人最初向用户提问,以在我的数据库中找到正确的项目标题,然后通过询问3-4个与该项目相关的支持问题返回给用户。问题必须是项目属性(品牌、颜色、尺寸…),并且会因项目而异。因此,聊天机器人将向下搜索用户以找到最佳项目。 你能帮我找到答案吗?我已经创建了代码,但它们不起作用,我不知道这有什么问题。如果您已经创建了这个文件,并且拥有index.js文件,我

我正在为我的“dialogflow”聊天机器人使用“firestore”数据库,我已经为一家在线杂货店创建了这个聊天机器人。问题是:我希望我的聊天机器人最初向用户提问,以在我的数据库中找到正确的项目标题,然后通过询问3-4个与该项目相关的支持问题返回给用户。问题必须是项目属性(品牌、颜色、尺寸…),并且会因项目而异。因此,聊天机器人将向下搜索用户以找到最佳项目。 你能帮我找到答案吗?我已经创建了代码,但它们不起作用,我不知道这有什么问题。如果您已经创建了这个文件,并且拥有index.js文件,我非常感谢您在这里推荐我

 index.js:

    'use strict';

const functions = require('firebase-functions');
// Import admin SDK
const admin = require('firebase-admin');
const {
  WebhookClient
} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
admin.initializeApp(functions.config().firebase);
// here we get the database in a variable
const db = admin.firestore();
const data = {...};
// Add a new document in collection "dialogflow" with document ID 'agent'
  const dialogflowAgentRef = db.collection('dialogflow').doc('agent').set(data); 
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({
    request,
    response
  });
 function writeToDb(agent) {
    // Get parameter from Dialogflow with the string to add to the database doc
    const databaseEntry = agent.parameters.databaseEntry;
  // Get the database collection 'dialogflow' and document 'agent' and store
    // the document  {entry: "<value of database entry>"} in the 'agent' document
      const dialogflowAgentRef = db.collection('dialogflow').doc('agent').where('title', '==', title);

    return db.runTransaction(t => {
      t.set(dialogflowAgentRef, {
        entry: databaseEntry
      });
      return Promise.resolve('Write complete');
    }).then(doc => {
      agent.add(`Wrote "${databaseEntry}" to the Firestore database.`);
    }).catch(err => {
      console.log(`Error writing to Firestore: ${err}`);
      agent.add(`Failed to write "${databaseEntry}" to the Firestore database.`);
    });
  }
function readFromDb(agent) {
    // Get the database collection 'dialogflow' and document 'agent'
    const dialogflowAgentDoc = db.collection('dialogflow/agent/rss/channel/item'); // .doc('agent')

    // Get the value of 'entry' in the document and send it to the user
    return dialogflowAgentDoc.get()
      .then(doc => {
        if (!doc.exists) {
          agent.add('No data found in the database!');
        } else {
          agent.add(doc.data().entry);
        }
        return Promise.resolve('Read complete');
      }).catch(() => {
        agent.add('Error reading entry from the Firestore database.');
        agent.add('Please add a entry to the database first by saying, "Write <your phrase> to the database"');
      });
  }
  // Map from Dialogflow intent names to functions to be run when the intent is matched
  let intentMap = new Map();
  intentMap.set('ReadFromFirestore', readFromDb);
  intentMap.set('WriteToFirestore', writeToDb);
  agent.handleRequest(intentMap);
});
index.js:
"严格使用",;
const functions=require('firebase-functions');
//导入管理SDK
const admin=require('firebase-admin');
常数{
WebhookClient
}=要求('dialogflow-fulfillment');
process.env.DEBUG='dialogflow:';//启用lib调试语句
admin.initializeApp(functions.config().firebase);
//在这里,我们得到一个变量中的数据库
const db=admin.firestore();
常量数据={…};
//在文档ID为“代理”的集合“dialogflow”中添加新文档
const dialogflowAgentRef=db.collection('dialogflow').doc('agent').set(数据);
exports.dialogflowFirebaseFulfillment=functions.https.onRequest((请求,响应)=>{
const agent=new-WebhookClient({
要求
响应
});
函数writeToDb(代理){
//使用要添加到数据库文档的字符串从Dialogflow获取参数
const databaseEntry=agent.parameters.databaseEntry;
//获取数据库集合“dialogflow”和文档“agent”并存储
//“代理”文档中的文档{条目:}
const dialogflowAgentRef=db.collection('dialogflow').doc('agent')。其中('title','==',title);
返回db.runTransaction(t=>{
t、 设置(对话框FlowAgentRef{
条目:数据库条目
});
返回承诺。解决(“填写完整”);
})。然后(doc=>{
add(`writed“${databaseEntry}”到Firestore数据库。`);
}).catch(错误=>{
log(`写入Firestore时出错:${err}`);
add(`未能将“${databaseEntry}”写入Firestore数据库。`);
});
}
函数readFromDb(代理){
//获取数据库集合“dialogflow”和文档“agent”
const dialogflowAgentDoc=db.collection('dialogflow/agent/rss/channel/item');/.doc('agent'))
//获取文档中“entry”的值并将其发送给用户
返回对话框flowAgentDoc.get()
。然后(doc=>{
如果(!doc.存在){
add('在数据库中找不到数据!');
}否则{
agent.add(单据数据()录入);
}
返回承诺。解决(“阅读完成”);
}).catch(()=>{
add('从Firestore数据库读取条目时出错');
add('请先向数据库添加一个条目,说“Write to the database”');
});
}
//从Dialogflow意图名称映射到意图匹配时要运行的函数
让intentMap=newmap();
intentMap.set('ReadFromFirestore',readFromDb);
intentMap.set('WriteToFirestore',writeToDb);
代理handleRequest(intentMap);
});

如您所示,您的代码存在许多问题,可能会导致Firestore数据库的读写出现问题

看起来您正试图使用该行查找要写入的现有集合

const dialogflowAgentRef = db.collection('dialogflow').doc('agent').where('title', '==', title);
但是
title
没有在任何地方定义,我怀疑这会导致错误。此外,
doc()
返回一个,但DocumentReference中没有
where()
方法

请记住,您需要使用交替的集合和文档来构建Firestore。因此,您的“firebase”集合可以包含一个名为“agent”的文档,并且该文档可能具有子集合

当你试着阅读的时候

const dialogflowAgentDoc = db.collection('dialogflow/agent/rss/channel/item');
你得到了一个集合,但试图把它当作一个文档。注释表明您试图从该集合中读取特定文档(这很有意义),但您是通过硬编码字符串“agent”加载该文档,而不是试图从Dialogflow传递给您的参数中获取agent

最后—读和写部分中的路径不匹配。在测试时,使用硬编码路径是可以的,但是请确保您使用的是匹配的路径,并且它们反映了集合/doc/collection/doc/。。。路径要求

因此,在这两种情况下,您可能有一个类似

const docTitle = agent.parameters.title;
const docRef = db.collection('dialogflow').doc(title);
如果您在Dialogflow中的意图中定义了一个“title”参数,它将使用此参数引用文档,然后您可以读取或写入文档。

谢谢您的回答,我已经将数据库更改为实时firebase而不是firestore。与支持相关的问题仍然存在问题。我想进入我的实时数据库,通过使用“oederByChild”和“equalTo”方法搜索来查找该项目,因为我在这个网站上找到了这些人的问题和答案。仍然无法通过我的数据库子项找到和项目标题。以下是编写的代码:
thanks for the answer I already changed my database to real time firebase instead of firestore. still having problem with support relevant questions. I want to go to my real time database to find the item by search using "oederByChild" and "equalTo" methods as I found these in people questions and answer in this website. still cannot find and item title through my database child. here is the codes are written:

'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {
    WebhookClient
} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements

admin.initializeApp(functions.config().firebase);
const db = admin.database();
// const ref = db.ref('server/saving-data/fireblog');
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));

    // Get the database collection 'dialogflow' and document 'agent' and store
    // the document  {entry: "<value of database entry>"} in the 'agent' document
    function writeToDb(agent) {
        const databaseEntry = agent.parameters.databaseEntry;
        const acc = db.ref('rss/channel/item/4/title'); //**This worked!  */
        acc.set({
            entry: databaseEntry
        });
        return Promise.resolve('write complete')
            .then(_acc => {
                agent.add(`Wrote ${databaseEntry} to the realtime database.`);
                return false;
            }).catch(err => {
                console.log(`Error writing to Firestore: ${err}`);
                agent.add(`Failed to write "${databaseEntry}" to the Firestore database.`);
            });
    }
    // and this is when we want to write to in the same child, keeping the old values:
    //const acc = db.ref('/rss/channel/item/5/color'); //**This worked!  */
    //const result = acc.child(databaseEntry).set({entry: databaseEntry});
    //agent.add(`Wrote ${databaseEntry} to the realtime database.`);
    //console.log(result.key);
    //});

    // to read data
    function readFromDb(agent) {
        const any = agent.parameters.any;
        agent.add(`Thank you...`);
        var rootRef = db.ref();
        var childref = rootRef.child("rss/channel/item");
        return childref.orderByChild("title").equalTo("Icebreaker").once("value").then(function(snapshot){ //has been taken from the bus example: https://stackoverflow.com/questions/51917390/dialogflow-how-do-i-pass-a-parameter-through-in-a-firebase-query
            var colored = snapshot.child("color/__text").val();
            var sized = snapshot.child("size/__text").val();
            agent.add(`Your search result for ` + any + ` Throughout the database is ` + colored +
                ` Color and ` + sized + ` Size`);
            return Promise.resolve('Read complete');
        }).catch(() => {
            agent.add('Error reading entry from the Firestore database.');
            agent.add('Please add a entry to the database first by saying, "Write <your phrase> to the database"');
        });
    }


    // Map from Dialogflow intent names to functions to be run when the intent is matched
    let intentMap = new Map();
    intentMap.set('IWannaBuy', readFromDb);
    intentMap.set('WriteToFirebase', writeToDb);
    agent.handleRequest(intentMap);
});



    enter code here

[this is how my database is][1]


  [1]: https://i.stack.imgur.com/QdFy5.png
"严格使用",; const functions=require('firebase-functions'); const admin=require('firebase-admin'); 常数{ WebhookClient }=要求('dialogflow-fulfillment'); process.env.DEBUG='dialogflow:';//启用lib调试语句 admin.initializeApp(functions.config().firebase); const db=admin.database(); //const ref=db.ref('server/saving data/fireblog'); exports.dialogflowFirebaseFulfillment=functions.https.onRequest((请求,响应)=>{ const agent=new-WebhookClient({ 要求 响应 }); log('Dialogflow请求头:'+JSON.stringify(Request.headers)); log('Dialogflow请求主体:'+JSON.stringify(Request.body)); //获取数据