dialogflow es fulfillment cannot connect to firebase - firebase

I had followed the video (link) to connect firebase to dialogflow, but there had some errors that I can’t realized.
I followed the video
My problem is dialogflow always shows
「Webhook call failed. Error: UNAVAILABLE, State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500.」
Firebase show
「Error : No handler for requested intent」
「Error : Process exited with code 16」
「Error : No handler for requested intent」
「Error : Process exited with code 16」
This is my firebase
firebase realtime image
This is my fulfillment
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const firebaseAdmin = require("firebase-admin");
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
firebaseAdmin.initializeApp({
credential:firebaseAdmin.credential.applicationDefault(),
databaseURL:'ws://coherent-lock-376605-default-rtdb.asia-southeast1.firebasedatabase.app/',
});
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) {
var dateTime = new Date();
agent.add(`HIHI! The time is :` + dateTime);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function getFromFirebase(agent){
return firebaseAdmin.database().ref('address').once("value").then((snapshot) =>{
var address = snapshot.child().val();
agent.add('hey! the address is :'+address);
});
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('地址', getFromFirebase);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
Can anyone help me to solve it?

Related

How to connect Realtime Database firebase with dialogflow chatbot

I want to connect Realtime database firebase with Dialogflow chatbot and how to get some data from Realtime database firebase using Dialogflow. I want when the user ask my chatbot to show the machine water quantity then chatbot will ask for the machine id of which you want to know water quantity, then chatbot access the realtime database firebase to check if the machine is present in database then it will show the water quantity of that machine.
I have tried to connect realtime database firebase this way-
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const firebaseAdmin=require("firebase-admin");
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
firebaseAdmin.initializeapp({
credential:firebaseAdmin.credential.applicationDefault(),
databaseURL:"ws://rtdb.asia-southeast1.firebasedatabase.app/",
});
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 Akvo chat!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
//function getFromFirebase(agent){
//return firebaseAdmin.database().ref("board_id").once("value", snapshot=>{
//var boardid=snapshot.val();
//agent.add(boardid);
//});
//}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
//intentMap.set('board id', getFromFirebase);
agent.handleRequest(intentMap);
});
But it shows an error.
Error: " Error happened during Cloud Functions Deployment "
can you please tell me how to do this.

Unity Firebase functions.https.onRequest call error is always Internal with error message: Response is not valid JSON object

I'm trying to handle Firebase cloud function errors in Unity but I cannot always receive an error with error code "Internal" and error message "Response is not valid JSON object."
After reading through the Firebase documentation and some other stack overflow questions I understand that there is a difference between functions.https.onCall and functions.https.onRequest. We are currently using onRequest because we need to access these functions from web, in addition to android and iOS.
The problematic cloud code:
app.post("/test", (req, res) => {
res.status(500).send("This message will never appear in the editor");
});
exports.app = functions.https.onRequest(app);
exports.ThisTestWorks = functions.https.onCall((data, context) => {
throw new functions.https.HttpsError('invalid-argument', 'This message will appear in the editor');
});
Unity code:
FirebaseProcess retVal = new FirebaseProcess();
FunctionInst.GetHttpsCallable("app/test").CallAsync(request).ContinueWith(t => {
if (t.IsFaulted || t.IsCanceled) {
foreach (var inner in t.Exception.InnerExceptions) {
if (inner is FunctionsException) {
var e = (FunctionsException) inner;
Debug.Log("e.ErrorCode: " + e.ErrorCode + ", e.Message: " + e.Message);
} else {
Debug.Log("inner.Message: " + inner.Message);
}
}
Debug.Log("t.Exception.Message " + t.Exception.Message);
Debug.Log("t.Status " + t.Status);
} else {
retVal.Success = true;
retVal.ResultJSON = t.Result.Data as string;
}
retVal.IsRunning = false;
});
This code will return the following logs:
e.ErrorCode: Internal, e.Message: Response is not valid JSON object.
t.Exception.Message One or more errors occurred.
t.Status Faulted
Full (relevant) cloud code:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const cors = require('cors')({origin: true});
const express = require('express');
const cookieParser = require('cookie-parser')();
const app = express();
admin.initializeApp();
const validateFirebaseIdToken = async (req, res, next) => {
if ((!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) &&
!(req.cookies && req.cookies.__session)) {
console.error('No Firebase ID token was passed as a Bearer token in the Authorization header.',
'Make sure you authorize your request by providing the following HTTP header:',
'Authorization: Bearer <Firebase ID Token>',
'or by passing a "__session" cookie.');
res.status(403).send('Unauthorized');
return;
}
let idToken;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
// Read the ID Token from the Authorization header.
idToken = req.headers.authorization.split('Bearer ')[1];
} else if(req.cookies) {
// Read the ID Token from cookie.
idToken = req.cookies.__session;
} else {
// No cookie
res.status(403).send('Unauthorized');
return;
}
try {
const decodedIdToken = await admin.auth().verifyIdToken(idToken);
req.user = decodedIdToken;
next();
return;
} catch (error) {
console.error('Error while verifying Firebase ID token:', error);
res.status(403).send('Unauthorized');
return;
}
};
app.use(cors);
app.use(cookieParser);
app.use(validateFirebaseIdToken);
app.post("/test", (req, res) => {
res.status(500).send("This message will never appear in the editor");
});
exports.ThisTestFails = functions.https.onRequest(app);
exports.ThisTestWorks = functions.https.onCall((data, context) => {
throw new functions.https.HttpsError('invalid-argument', 'This message will appear in the editor');
});
Is there a reason that this doesn't return a custom error in the Unity editor? What am I missing here?
Thanks in advance!

dialogflow and firebase - cannot read data from firebase

Below is my fulfilment inline code
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
// initialise DB connection
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'ws://rochechatbot.firebaseio.com/',
});
process.env.DEBUG = 'dialogflow:debug';
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 handleData(agent) {
const Product_name = agent.parameters.Product_name;
agent.add('Hello');
return admin.database().ref('rochechatbot').once("value").then((snapshot) => {
var StockData = snapshot.child("Stock").val();
agent.add(StockData);
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('StockLevelEnquiry', handleData);
agent.handleRequest(intentMap);
});
Below is my firebase DB
Below is my dialogflow, webhook is enabled
Wonder why even 'hello" is not being returned?
how to read the data from the firebase?

Unable to fetch data from firestore database

I am working on a dialogflow agent and using fulfillment to fetch data from the firestore.
I have a firestore collection called Users which has name and location fields. But am getting the error which causes the fetching of data to fail.
Warning, estimating Firebase Config based on GCLOUD_PROJECT.
Initializing firebase-admin may fail
The fulfillment code for the agent is as follows
'use strict';
const functions = require('firebase-functions');
const { WebhookClient } = require('dialogflow-fulfillment');
const { Card, Suggestion } = require('dialogflow-fulfillment');
const admin = require('firebase-admin');
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));
var name='';
var location='';
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
function getUserDetails(agent)
{
name= agent.parameters.name;
location=agent.parameters.location;
console.log("buyer name is " + name);
db.collection("Users").doc("101").set({
name: name,
location:location});
agent.add(`User has been inserted`);
}
intentMap.set('Buy Car', getUserDetails);
agent.handleRequest(intentMap);
})
This form of initialization for the Firebase Admin SDK is deprecated:
admin.initializeApp(functions.config().firebase);
You should initialize like this instead:
admin.initializeApp();

Unable to send SMS through Twilio and Google Functions

I am attempting to send a text (a one-time pass code) using Twilio, firebase and Google Functions, and using Postman.
I have run $ npm install --save twilio#3.0.0 -rc.13 in the functions directory.
When I run $ firebase deploy, it completes. But on Postman, when I do POST, Body and feed a JSON { "phone": "555-5555" }, I get an "Error: could not handle the request."
I am able to send a text in Twilio Programmable SMS from my Twilio number to an actual outside number direct to the mobile phone. I'm using live credentials for Sid and AuthToken.
Is this an issue with Twilio, Google Functions and some configurations?
Here are the logs on Functions:
// White flag sign//
Function execution took 1452 ms, finished with status: 'crash'
//Red Warning sign//
TypeError: handler is not a function
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:26:41)
at /var/tmp/worker/worker.js:676:7
at /var/tmp/worker/worker.js:660:9
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
Also, the google eslint forces consistent-return, which is why I put "return;" in the request-one-time-password.js. I cannot seem to turn it off by adding "consistent-return": 0 in eslintrc.
My code(with secret keys and phone numbers redacted):
//one-time-password/functions/service_account.js
has my keys copied and pasted.
//one-time-password/functions/twilio.js
const twilio = require('twilio');
const accountSid = 'redacted';
const authToken = 'redacted';
module.exports = new twilio.Twilio(accountSid, authToken);
//one-time-password/functions/request-one-time-password.js
const admin = require('firebase-admin');
const twilio = require('./twilio');
module.export = function(req, res) {
if(!req.body.phone) {
return res.status(422).send({ error: 'You must provide a phone number!'});
}
const phone = String(req.body.phone).replace(/[^\d]/g, '');
admin.auth().getUser(phone).then(userRecord => {
const code = Math.floor((Math.random() * 8999 + 1000));
// generate number between 1000 and 9999; drop off decimals
twilio.messages.create({
body: 'Your code is ' + code,
to: phone,
from: '+redacted'
}, (err) => {
if (err) { return res.status(422).send(err); }
admin.database().ref('users/' + phone).update({ code: code, codeValid: true }, () => {
res.send({ success: true });
})
});
return;
}).catch((err) => {
res.status(422).send({ error: err })
});
}
/////////////////////////////////
//one-time-password/functions/index.js
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const createUser = require('./create_user');
const serviceAccount = require('./service_account.json')
const requestOneTimePassword = require('./request_one_time_password');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://one-time-password-650d2.firebaseio.com"
});
exports.createUser = functions.https.onRequest(createUser);
exports.requestOneTimePassword =
functions.https.onRequest(requestOneTimePassword);
You have
module.exports = new twilio.Twilio(accountSid, authToken);
on one line, and further down
module.export = function(req, res) { ... }.
Try changing export to exports.
One thing that tripped me up for a long time was how twilio sent the request body to the cloud function. It sends it in a body object so to access your request body it will look something like this
req.body.body
On top of that it passed it as a JSON string so I had to JSON.parse()
Example I got working:
export const functionName= functions.https.onRequest((req, res) => {
cors(req, res, () => {
let body = JSON.parse(req.body.body);
console.log(body);
console.log(body.service_id);
res.send();
});
});
This also may depend on the Twilio service you are using. I was using their Studio HTTP Request Module.
Hope this helps a little, not sure if it was your exact problem though :(

Resources