Диалог потока chatbot, как зайти в базу данных firestore и вернуться с вопросами поддержки? - PullRequest
0 голосов
/ 11 сентября 2018

Я использую базу данных "firestore" для моего чат-бота "dialogflow", который я уже создал для онлайн-магазина.Проблема в том, что я хочу, чтобы мой чат-бот сначала задавал вопросы пользователям, чтобы найти правильный заголовок элемента в моей базе данных, а затем возвращался к пользователю, задавая 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);
});

Ответы [ 2 ]

0 голосов
/ 29 октября 2018
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
0 голосов
/ 12 сентября 2018

Существует ряд проблем с вашим кодом, поскольку вы показали его, которые могут вызвать проблемы чтения и записи с базой данных Firestore.

Похоже, вы пытаетесь найти существующую коллекцию для записисо строкой

const dialogflowAgentRef = db.collection('dialogflow').doc('agent').where('title', '==', title);

, но title нигде не определено, что, как я подозреваю, вызывает ошибку.Кроме того, doc() возвращает DocumentReference , но в DocumentReference нет метода where().

Помните, что вам необходимо структурировать Firestore, используя чередующиеся коллекции и документы.Таким образом, ваша коллекция «firebase» может содержать документ с именем «agent», и этот документ может иметь вложенные коллекции.

Когда вы пытаетесь читать с помощью

const dialogflowAgentDoc = db.collection('dialogflow/agent/rss/channel/item');

Вы получаетеколлекции, но затем пытаюсь рассматривать это как документ.Комментарий предполагает, что вы пытаетесь прочитать конкретный документ из этой коллекции (что имеет смысл), но вы загружаете этот документ с помощью жестко закодированной строки «агент», а не пытаетесь получить агент из переданных параметровВам из Dialogflow.

Наконец - пути в разделах чтения и записи не совпадают.Использование жестко закодированных путей - это хорошо при тестировании, но убедитесь, что вы используете совпадающие пути и что они соответствуют требованию пути сбора / doc / collection / doc / ....

Итак, в обоих случаях выможет иметь ссылку, которая выглядит примерно так:

const docTitle = agent.parameters.title;
const docRef = db.collection('dialogflow').doc(title);

, которая, если вы определили параметр "title" в ваших Intents в Dialogflow, будет использовать его для ссылки на документ, который вы затем сможете читать или писать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...