I am using Firebase to host my nodejs app and am using Cloud Functions.
Using the command firebase serve --only functions,hosting
I am deploying my app.
I have a form with action="/putNPK"
and works perfectly when run from node.
But when I serve it through firebase , I am getting this error when I submit the form.
{"error":{"code":404,"status":"NOT_FOUND","message":"/putNPK is not a recognized path.","errors":["/putNPK is not a recognized path."]}}
How to fix this?
firebase.json looks like this :-
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"rewrites": [
{
"source": "**",
"function": "app"
}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"trailingSlash": true
}
}
This is my folder structure :-
Contents of index.js :-
const admin = require("firebase-admin") ;
const express = require("express") ;
const app = require("express")() ;
const bodyparser = require("body-parser") ;
const functions = require("firebase-functions") ;
const request_controller = require("./requests_controller") ;
app.use(express.static('../public/assets/')) ;
app.use(express.static('../public/')) ;
request_controller(app) ;
app.use((req ,res , next)=>{
res.status(404).redirect('404.html') ;
})
app.listen(8000) ;
exports.app = functions.https.onRequest(app) ;
COntents of requests_controller file (module imported in index.js) :-
const admin = require("firebase-admin") ;
const bodyparser = require("body-parser") ;
const app = require("express")() ;
const urlencodedParser =bodyparser.urlencoded({extended : true}) ;
const posthandler = require("posthandler") ;
const gethandler = require("gethandler") ;
var serviceAccount = require("C:/Users/Natesh/Documents/raita-mitra-2018-firebase-adminsdk (acnt nateshmbhat1).json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://raita-mitra-2018.firebaseio.com"
});
//Validates POST request body and checks if the request contains all the keys('strings') in the array sent as keys argument
function validatePostBody(req , res , keys ){
for(i in keys){
if(!(keys[i] in req.body))
{
console.log("invalid post request returning ! ") ;
return false ;
}
}
return true ;
}
module.exports = function Handle_requests(app)
{
console.log('Request Handler started ! ') ;
app.get('/' , (req , res)=>{
res.sendFile(__dirname + '/index.html') ;
})
app.get('/home' , (req , res)=>{
res.sendFile(__dirname + '/index.html') ;
})
app.post('/putNPK', urlencodedParser ,(req , res)=>{
if(!validatePostBody(req , res , ['fertilizer' ,'crop' , 'nitrogen' , 'phone' , 'phosphorus' , 'potassium'])) return ;
ref = admin.database().ref('/users/' + req.body.phone) ;
ref.set(req.body) ;
console.log("Added to firebase database") ;
res.status(200).redirect('/') ;
admin.messaging().sendToTopic('global' , {
notification : {
title : 'Farmer Project' ,
body : 'notification body'
} ,
data : {
nitrogen : req.body.nitrogen
}
})
} )
}
I found a simple fix for this :-
"/path" (with a slash before 'path') works in nodejs but not in firebase.
"path" (without the SLASH) works both in nodejs and firebase.
Instead of action ="/postpath"
, it should be action="postpath"
. This ensures that the get and post request go to the express router in a relative path manner which firebase forwards to the concerned function .
If the path is not relative , for example if ur running a localserver , then action="/postpath"
resolves to localhost:8000/postpath
which works fine in nodejs but in firebase it doesn't work since firebase's function has its own URL over the firebase hosting server .
Therefore localhost:8000/postpath
won't even get passed to our express app function handler.
But when action="postpath"
is used , it resolves this as http://localhost:5001/<project-id>/us-central1/app/postpath
and now works perfectly.
Also if one or more of your static files are not getting served , (you are getting 404 error) , it might be because you have included your <script src="/path">
with a slash at the beginning of the source .
Remove the /
and it works flawlessly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With