In Firebase Functions showing Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail - error message - firebase

I do receive an error message while deploying.
In Firebase Functions showing Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail
I have already define all the apikey etc but the database is not linked dialogflow.
Please advise.
const functions = require('firebase-functions');
var config = {
apiKey: xxxxx,
authDomain: xxxxx,
databaseURL: xxxxx,
projectId: xxxxx,
storageBucket: xxxxx,
messagingSenderId: xxxxx,
;// your config object could be differ
const admin = require('firebase-admin');
admin.initializeApp(config);
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
const db = admin.database();
const action = request.body.queryResult.action;
if (action === 'product_description') {
const product = request.body.queryResult.parameters.Products.trim();
const ref = db.ref(`products/${product.toLowerCase()}/description`);
ref.once('value').then((snapshot) => {
const result = snapshot.val();
if (result === null) {
response.json({
fulfillmentText: `Product does not exists in inventory`
});
return;
}
response.json({
fulfillmentText: `Here is the description of ${product}: ${result}`,
source: action
});
}).catch((err) => {
response.json({
fulfillmentText: `I don't know what is it`
});
});
} else if(action === 'product_quantity') {
const product = request.body.queryResult.parameters.Products.trim();
const ref = db.ref(`products/${product.toLowerCase()}`);
ref.once('value').then((snapshot) => {
const result = snapshot.val();
if (result === null) {
response.json({
fulfillmentText: `Product does not exists in inventory`
});
return;
}
if (!result.stock) {
response.json({
fulfillmentText: `Currently ${product} is out of stock`,
source: action
});
} else {
response.json({
fulfillmentText: `We have ${result.stock} ${product} in stock`,
source: action
});
}
}).catch((err) => {
response.json({
fulfillmentText: `I don't know what is it`
});
});
} else {
response.json({
fulfillmentText: `I don't know what is it`
});
}
});`
This is the my 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": "8"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.12.0",
"firebase-admin": "^8.8.0",
"firebase-functions": "^3.3.0",
"dialogflow": "^0.12.1",
"dialogflow-fulfillment": "^0.6.1"
}
}

Related

Firebase storage-resize-images not triggered by bucket upload

I'm using a Firebase function to upload images to Storage.
I installed the extension firebase/storage-resize-images#0.1.29
When I upload an image directly within the dashboard, the resize happens.
However, images uploaded with my functions do not trigger the resize.
What am I missing here?
async function migrateImageFromURL (folder, url, name, callback) {
const {filePath, fileName} = await downloadRemoteUrlImage(url, name.split('.')[0])
const bucket = admin.storage().bucket();
const destination = `dev/${folder}/${fileName}`;
try {
await bucket.upload(filePath, {
destination: destination,
gzip: true,
metadata: {
fileName,
contentType: `image/${fileName.split('.')[1]}`,
cacheControl: 'public, max-age=31536000',
},
});
callback(destination)
}
catch (e) {
throw new Error("uploadLocalFileToStorage failed: " + e);
}
return ''
};
Create a cloud function with busyboy
Create a sample firebase function
Copy the code for package.json
Run the command to install the node modules
npm run
Copy the code for index.js
To generate a private key file for your service account:
In the Firebase console, open Settings > Service Accounts.
Click Generate New Private Key, then confirm by clicking Generate Key.
Choose Node Js
Securely store the JSON file containing the key.
Copy the firebase-admin-sdk.json file inside the function directory
Deploy the function to firebase
firebase deploy --only functions
Get the http endpoint from the firebase console
Index.js
const functions = require("firebase-functions");
const os = require("os");
const path = require("path");
const spawn = require("child-process-promise").spawn;
//To enable Cross AXIS
//Change to False to avoid DDOS
const cors = require("cors")({ origin: true });
//Parse Files
const Busboy = require("busboy");
//Files System
const fs = require("fs");
var gcconfig = {
// Get the project ID from firebaserc
projectId: "<project_id>",
// Write the name of the file in the root director which contains the private key of firebase-admin-sdk
keyFilename: "firebase-admin-sdk.json"
};
// const gcs = require("#google-cloud/storage")(gcconfig);
const {Storage} = require('#google-cloud/storage');
const gcs = new Storage(gcconfig);
exports.uploadFile = functions.https.onRequest((req, res) => {
//Allowing CROSS SITE
cors(req, res, () => {
if (req.method !== "POST") {
return res.status(500).json({
message: "Not allowed"
});
}
console.log("Starting BusBOY");
const busboy = Busboy({ headers: req.headers});
let uploadData = null;
//File parsing
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
// Firebase cloudfunction will have some tmpdirectory tmpdir
// It will be cleaned up after execution
console.log("File function reached ");
console.log("Temp folder is "+os.tmpdir());
console.log("File name is "+filename.filename);
const filepath = path.join(os.tmpdir(),filename.filename);
console.log("Location of file is "+filepath);
uploadData = { file: filepath, type: mimetype };
console.log("Writing to temp file storage");
//Writing file to storage
file.pipe(fs.createWriteStream(filepath));
//Extra Details such as limit error
file.on('limit', () => {
console.log("Reached size limit");
debugLog(options, `Size limit reached for ${field}->${filename.filename}, bytes:${getFilesizeInBytes(filename)}`);
});
file.on('end', () => {
const size = getFilesizeInBytes(filename.filename);
console.log("File size is "+size+" bytes");
});
file.on('error', (err) => {
console.log("File format error");
});
});
//For Form data Listener
// busboy.on("field",()=>{
// });
// Finishes the whole process, only upload after that
busboy.on("finish", () => {
// Firebase storage, Inside the console itself
// Copy the folder location
// gs://<Project_id>.appspot.com
// Remove the gs String
console.log("Finished BusBoy");
var your_project_id="<your_project_id>.appspot.com";
const bucket = gcs.bucket(your_project_id);
console.log("Uploading Image to firebase");
bucket
.upload(uploadData.file, {
uploadType: "media",
metadata: {
metadata: {
contentType: uploadData.type
}
}
})
.then(() => {
// Success
console.log("Uploaded Successfully");
res.status(200).json({
message: "It worked!"
});
})
.catch(err => {
// Error
console.log("Error while uploading");
res.status(500).json({
error: err
});
});
});
//End the parsing
console.log("End Parsing");
busboy.end(req.rawBody);
});
});
//Finding the file size from the filename
function getFilesizeInBytes(filename) {
var stats = fs.statSync(filename);
var fileSizeInBytes = stats.size;
return fileSizeInBytes;
}
package.json
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions:uploadFile",
"logs": "firebase functions:log"
},
"engines": {
"node": "14"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1",
"#google-cloud/storage": "^6.0.1",
"busboy": "^1.6.0",
"child-process-promise": "^2.2.1",
"cors": "^2.8.5"
},
"devDependencies": {
"firebase-functions-test": "^0.2.0"
},
"private": true
}
For more details
Checkout https://github.com/katmakhan/firebase-course/tree/master/Firebase%20Cloud%20Function/Image%20Uploader

How to upload files to firebase storage using rest api in unity

I want to upload files to firebase storage using the rest API from unity. It is like clicking the browse button, browsing on local storage, selecting files, and then uploading.
How do I do this?
Create a cloud function with busyboy
Create a sample firebase function
Copy the code for package.json
Run the command to install the node modules
npm run
Copy the code for index.js
To generate a private key file for your service account:
In the Firebase console, open Settings > Service Accounts.
Click Generate New Private Key, then confirm by clicking Generate Key.
Choose Node Js
Securely store the JSON file containing the key.
Copy the firebase-admin-sdk.json file inside the function directory
Deploy the function to firebase
firebase deploy --only functions
Get the http endpoint from the firebase console
Index.js
const functions = require("firebase-functions");
const os = require("os");
const path = require("path");
const spawn = require("child-process-promise").spawn;
//To enable Cross AXIS
//Change to False to avoid DDOS
const cors = require("cors")({ origin: true });
//Parse Files
const Busboy = require("busboy");
//Files System
const fs = require("fs");
var gcconfig = {
// Get the project ID from firebaserc
projectId: "<project_id>",
// Write the name of the file in the root director which contains the private key of firebase-admin-sdk
keyFilename: "firebase-admin-sdk.json"
};
// const gcs = require("#google-cloud/storage")(gcconfig);
const {Storage} = require('#google-cloud/storage');
const gcs = new Storage(gcconfig);
exports.uploadFile = functions.https.onRequest((req, res) => {
//Allowing CROSS SITE
cors(req, res, () => {
if (req.method !== "POST") {
return res.status(500).json({
message: "Not allowed"
});
}
console.log("Starting BusBOY");
const busboy = Busboy({ headers: req.headers});
let uploadData = null;
//File parsing
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
// Firebase cloudfunction will have some tmpdirectory tmpdir
// It will be cleaned up after execution
console.log("File function reached ");
console.log("Temp folder is "+os.tmpdir());
console.log("File name is "+filename.filename);
const filepath = path.join(os.tmpdir(),filename.filename);
console.log("Location of file is "+filepath);
uploadData = { file: filepath, type: mimetype };
console.log("Writing to temp file storage");
//Writing file to storage
file.pipe(fs.createWriteStream(filepath));
//Extra Details such as limit error
file.on('limit', () => {
console.log("Reached size limit");
debugLog(options, `Size limit reached for ${field}->${filename.filename}, bytes:${getFilesizeInBytes(filename)}`);
});
file.on('end', () => {
const size = getFilesizeInBytes(filename.filename);
console.log("File size is "+size+" bytes");
});
file.on('error', (err) => {
console.log("File format error");
});
});
//For Form data Listener
// busboy.on("field",()=>{
// });
// Finishes the whole process, only upload after that
busboy.on("finish", () => {
// Firebase storage, Inside the console itself
// Copy the folder location
// gs://<Project_id>.appspot.com
// Remove the gs String
console.log("Finished BusBoy");
var your_project_id="<your_project_id>.appspot.com";
const bucket = gcs.bucket(your_project_id);
console.log("Uploading Image to firebase");
bucket
.upload(uploadData.file, {
uploadType: "media",
metadata: {
metadata: {
contentType: uploadData.type
}
}
})
.then(() => {
// Success
console.log("Uploaded Successfully");
res.status(200).json({
message: "It worked!"
});
})
.catch(err => {
// Error
console.log("Error while uploading");
res.status(500).json({
error: err
});
});
});
//End the parsing
console.log("End Parsing");
busboy.end(req.rawBody);
});
});
//Finding the file size from the filename
function getFilesizeInBytes(filename) {
var stats = fs.statSync(filename);
var fileSizeInBytes = stats.size;
return fileSizeInBytes;
}
package.json
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions:uploadFile",
"logs": "firebase functions:log"
},
"engines": {
"node": "14"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1",
"#google-cloud/storage": "^6.0.1",
"busboy": "^1.6.0",
"child-process-promise": "^2.2.1",
"cors": "^2.8.5"
},
"devDependencies": {
"firebase-functions-test": "^0.2.0"
},
"private": true
}
For more details
Checkout https://github.com/katmakhan/firebase-course/tree/master/Firebase%20Cloud%20Function/Image%20Uploader

Code problem in DialogFlow Fulfillment as it does not recognize Firebase asynchronous functions

I'm having problems because the code I made in the DialogFlow Fulfillment index.js when I took the context parameters he was unable to send talking to the DialogFlow support I was informed that the DialogFlow Fulfillment does not recognize asynchronous functions so when I use the "push" from Firebase to send the parameters he doesn't send anything I believe he expects some parameter from the context but because he doesn't receive it he skips the push function and ends up not executing and doesn't send anything.
DialogFlow Fulfillment index.js code:
const functions = require('firebase-functions');
const { WebhookClient } = require('dialogflow-fulfillment');
const { Card, Suggestion } = require('dialogflow-fulfillment');
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'https://testechatbot-2020.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 Mensagem(agent) {
var context = agent.context.get('awainting_nome');
var nome = context.parameters.nome;
var mensagem = agent.parameters.mensagem;
let teste = nome + " " + mensagem;
try {
admin.database().ref('Dados/').push({
Nome: nome,
Mensagem: mensagem
});
} catch (err) {
console.error(err);
return;
}
}
let intentMap = new Map();
intentMap.set('EntradaMensagem', Mensagem);
agent.handleRequest(intentMap);
});
DialogFlow Fulfillment package.json code:
{
"name": "dialogflowFirebaseFulfillment",
"description": "Fluxo com envio de parametros para o Firebase",
"version": "1.0.0",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"esversion": 8,
"engines": {
"node": ">=10.0.0"
},
"scripts": {
"start": "firebase serve",
"deploy": "firebase deploy"
},
"dependencies": {
"#google-cloud/firestore": "^0.16.1",
"firebase-admin": "^8.13.0",
"actions-on-google": "^2.2.0",
"firebase-functions": "^3.7.0",
"dialogflow": "^1.2.0",
"dialogflow-fulfillment": "^0.6.0",
"#google-cloud/dialogflow": "^3.0.0",
"node-fetch": "^2.6.0"
}
}
Image with response from DialogFlow support about asynchronous functions
response from DialogFlow support
I'm not sure where you heard that the Intent Handler can't support async functions. They most certainly can. If you're using an async function (or a function that returns a Promise - same thing), you either must declare it an async function or return the Promise.
Your handler function should look something more like
function Mensagem(agent) {
var context = agent.context.get('awainting_nome');
var nome = context.parameters.nome;
var mensagem = agent.parameters.mensagem;
let teste = nome + " " + mensagem;
return admin.database().ref('Dados/').push({
Nome: nome,
Mensagem: mensagem
})
.then( snapshot => {
agent.add( "pushed" );
})
.catch (err => {
console.error(err);
agent.add( "Error." );
})
}

Dialogflow connect to MQTT broker using Firebase?

I'm trying to use the Cloud Functions for Firebase to make a Dialogflow intent result in an MQTT message being published. I've managed to get the data I needed and all I still am not able to accomplish is:
Establishing a connection to the MQTT broker;
Publishing to said broker.
As the second one requires the former, it is not my concern yet.
The way I see it is: either my code is wrong or MQTT is included in what Firebase calls "external network". And I'm here, mainly, to make sure I don't upgrade to a paid plan for nothing.
index.js:
'use strict';
const functions = require('firebase-functions');
const { WebhookClient, Card, Suggestion } = require('dialogflow-fulfillment');
var mqtt = require('mqtt');
process.env.DEBUG = 'dialogflow:debug';
const HOST = 'broker.mqttdashboard.com';
const PORT = 1883;
const TOPIC = 'topic/voice_recog';
exports.dialogflowFirebaseFulfillment = functions.region('europe-west1').https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
try {
function publishParameter(agent) {
let message = agent.parameters.param_test;
return publishToMqtt(message).then((output) => {
agent.add(output);
}).catch(error => {
agent.add('error from publishToMqtt');
});
}
let intentMap = new Map();
intentMap.set('Repeat parameter', publishParameter);
agent.handleRequest(intentMap);
}
catch (err) {
console.error(err);
agent.add(err.message);
agent.send_();
}
});
function publishToMqtt(message) {
console.log("------------------------------");
console.log("Topic: \""+TOPIC+"\"");
console.log("Message: \""+message+"\"");
console.log("------------------------------");
return new Promise((resolve, reject) => {
var options = {
port: PORT,
host: HOST,
clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
keepalive: 60,
reconnectPeriod: 1000,
protocolId: 'MQIsdp',
protocolVersion: 3,
clean: true,
encoding: 'utf8'
};
var client = mqtt.connect("mqtt://"+HOST, {port: PORT});
// is not executed
client.on('connect', function () {
console.log('client connected');
});
// is not executed
client.publish(TOPIC, message, {}, function (err) {
console.log("Tried publishing \""+message+"\" to \""+TOPIC+"\".");
if (err) {
console.log("But the future refused to change:" + err);
reject();
}
else {
resolve(message);
client.end();
clearTimeout(noResp);
}
});
let noResp = setTimeout(() => {
console.log("No connection"); // always gives this result
reject();
client.end();
}, 5000);
});
}
package.json:
{
"name": "assistant-to-mqtt",
"description": "publishes intent parameter to MQTT broker",
"engines": {
"node": "8"
},
"version": "0.0.1",
"private": true,
"scripts": {
"start": "firebase serve --only functions:publish_mqtt",
"deploy": "firebase deploy --only functions:publish_mqtt"
},
"dependencies": {
"actions-on-google": "^2.1.3",
"dialogflow-fulfillment": "^0.4.1",
"firebase-admin": "^5.12.1",
"firebase-functions": "^2.2.1",
"mqtt": "^2.13.0"
}
}
All help is appreciated. Thank you.
EDIT: The log.
You are actually using a MQTT Broker which is treated as an external access URL by Firebase. Try enabling the billing as described here.

Error message in `Firebase` function log:

I am trying to read data in Firebase - Cloud Firestore database in Dialogflow. But not able to connect to the database and getting the following error in log:
Warning, estimating Firebase Config based on GCLOUD_PROJECT.
Initializing firebase-admin may fail
Code is in welcome intent fulfillment - Inline Editor(Powered by Cloud Functions for Firebase)
Collection Name in Cloud Firestore - users
document - 10 and 11 (totally 2)
field - book_id and text
Can someone please help me resolve this one or face similar issue.?
I have tried different solutions provided for this error faced by others, but none of it has solved mine.
Tried changing node version to 8 in package.json
Tried Initializeapp as below:
const admin = require('firebase-admin');
const app = dialogflow({debug: true});
admin.initializeApp();
Its not going inside app.intent(welcome) itself
index.js
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const axios = require('axios');
const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const admin = require('firebase-admin');
const app = dialogflow({debug: true});
admin.initializeApp();
const db = admin.firestore();
db.settings({timestampsInSnapshots: true});
const collectionRef = db.collection('users');
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));
/*function welcome(agent) {
agent.add(`Welcome to my agent!`);
}*/
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
app.intent('welcome', (conv) => {
console.log("welcome agent invoked");
const book = (agent.parameters.book).toString();
const termRef = collectionRef.doc('10');
return termRef.get()
.then((snapshot) => {
const {text, book_id} = snapshot.data();
conv.ask(`Here you go, ${text}, ${book_id}. ` +
`What else do you want to know?`);
console.log('text:', +text);
console.log('book_id:', +book_id);
}).catch((e) => {
console.log('error:', e);
conv.close('Sorry, try again');
});
});
});
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": "8"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.2.0",
"firebase-admin": "^5.13.1",
"firebase-functions": "^2.0.2",
"dialogflow": "^0.6.0",
"dialogflow-fulfillment": "^0.5.0"
}
}
Trying to get book_id value and text value from collection users in cloud firestore

Resources