I'm new at this & I've read numerous similar articles but none worked for me. I really need close assistance. I'm developing a chatbot using Dialogflow & using the Fulfillment Inline Editor. I wanted an intent where when user enters "Read db" the readDB() function will be triggered and the data from database will be stored in a custom payload. Here is my code:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const {Payload} = require("dialogflow-fulfillment");
const serviceAccount = {
"type": "service_account",
"project_id": xxx,
"private_key_id": xxx,
"private_key": xxx,
"client_email": xxx,
"client_id": xxx,
"auth_uri": xxx,
"token_uri": xxx,
"auth_provider_x509_cert_url": xxx
"client_x509_cert_url": xxx
};
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://repro-ljcq.firebaseapp.com/"
});
const db = admin.firestore();
db.settings({timestampsInSnapshots: true});
process.env.DEBUG = 'dialogflow:debug';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function displayDB(){
return admin.firestore().collection('ICR').doc(sessionID).get()
.then(doc => {
data = doc.data();
const payload = {
"accordion": {
"title": "Individual Client Record",
"group": data.groups,
"age": data.age,
"birthdate": data.birthdate,
"name": data.fullname,
"phonenumber": data.contactnumber,
"address": data.address,
"sex": data.sex,
"civilstatus": data.civilstatus
}
};
agent.add(new Payload(agent.UNSPECIFIED, payload, {rawPayload: true, sendAsMessage: true}));
});
}
let intentMap = new Map();
intentMap.set('ReadDB', displayDB);
agent.handleRequest(intentMap);
});
This is what my Database Structure looks like.
In my client-side app, it works fine when I use dummy values. This is what it was supposed to look like.
I can view the data in the logs, but receive "unhandled rejection" error message whenever I try to put it in the payload. Here is the logs:
I don't know whether this is from the wrong execution of the payloads or because of the timeout (retrieving data from firebase takes longer than 5s that it reaches Dialogflow timeout)
I really need help :/
Found the answer! Had to restructure the promise into something like this and upgrade my dependencies.
index.js
return admin.firestore().collection('ICR').doc(sessionID).get().then((doc) => {
const data = doc.data();
console.log(data);
return data;
}).then(data => {
if (data){
payload = {
"accordion": {
"filename": sessionID,
"title": "Individual Client Record",
"name": data.fullname,
"age": data.age + " years old",
"sex": data.gender,
"civilstatus": data.civilstatus,
"birthdate": data.birthdate,
"phonenumber": data.phonenumber,
"group": data.group,
"address": data.address
}
};
agent.add(new Payload(agent.UNSPECIFIED, payload, {rawPayload: true, sendAsMessage: true}));
} else {
//do something
}
}).catch(err => {
console.log(`Error fetching to Firestore.`);
});
package.json
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.5.0",
"firebase-admin": "^7.0.0",
"firebase-functions": "^2.2.0",
"dialogflow": "^0.8.0",
"dialogflow-fulfillment": "^0.6.1"
}
}
Code highly influenced from mikkipastel.