Now I created a file by node server like
const functions = require("firebase-functions")
const express = require("express")
/* Express */
const app = express()
app.get("/test", (request, response) => {
response.send("Hello from Express on Firebase!")
})
const api1 = functions.https.onRequest(app)
module.exports = {
api1
}
firebase.json
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
}
}
and I have deployed it to firebase hosting and try tried access it on firebase hosting the index.html show up to me but when I require the /test it's return as 404.html page ! what's I'm missing ?
after updated firebase.json and added rewrites to
{
"hosting":
{
"public": "public",
"rewrites": [
{
"source": "/test",
"function": "app"
}
]
}
}
the message is different now
The answer
I must to structured my project files to
-project (folder)
---functions (folder)(contains on all nodejs files)
---public (filder)
You need to include a rewrites section to your firebase.json file. That tells the Firebase servers how to route any requests that come in... and right now, you aren't telling it anything.
"hosting": {
"rewrites": [
{
"source": "**",
"function": "api1"
}
]
}
This answer isn't actually an answer to your question, but it demonstrates the proper way to set up rewrites with cloud function express apps.
Related
I started a Quasar V2 app using the quasar CLI with vite config and ssr build. I can't seem to return the firebase functions handler from dist/ssr/index.js as suggested in the docs.
I've tried this with the webpack Quasar V2 config and it works fine.
I ran firebase init then installed firebase-functions and firebase-admin in the root dir.
I changed the source of functions to dist/ssr where I built my ssr app. I also edited hosting to send requests to the function "handler".
firebase.json
"functions": {
"source": "dist/ssr",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
},
"hosting": {
"public": "dist/ssr",
"rewrites": [
{
"source": "**",
"function": "handler"
}
],
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
},
I then returned the handler function, following the instructions from the quasar docs
server.js
import * as functions from "firebase-functions";
export const listen = ssrListen(async ({ app, port, ssrHandler }) => {
if (process.env.DEV) {
await isReady();
return app.listen(port, () => {
if (process.env.PROD) {
console.log("Server listening at port " + port);
}
});
} else {
return {
handler: functions.https.onRequest(ssrHandler),
};
}
});
I then ran "npm install" on both the root directory and the dist/ssr directory to make sure everything is fine.
then when I ran "firebase serve" I get back this result in localhost:5000 "Function us-central1-handler does not exist, valid functions are:" Whats going on :(
I am trying to setup firebase with a domain so that:
My functions are available on mydomain.com/api/functionName
My hosting is available on mydomain.com (or preferably mydomain.com/client/, but the other will work as well)
My firebase.json looks like this:
{
"hosting": {
"public": "build",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
},
{
"source": "/api/helloWorld",
"function": "helloWorld"
}
]
}
}
After deploying this and accessing the domain in the browser, both / and /api/helloWorld routes will always take my to my client app, not to my function.
What's really weird to me is that when running the emulator locally, hosting does not work at all but localhost:5000/api/helloWorld works as expected and calls the function.
What am I doing wrong here? It feels as if my firebase.json is not deployed at all.
Update
Here's my function definition if that has anything to do with it:
exports.helloWorld = functions
.region("europe-west3")
.https.onRequest((_, response) => {
response.send("Hello from Firebase!");
});
Rewrites work in a "first match wins" order. Since you have a ** at the top, it will match all URLs and the second rewrite is never accessed. If you switch the order, you should see it work as expected:
{
"hosting": {
// ...
"rewrites": [
{
"source": "/api/helloWorld",
"function": "helloWorld"
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}
I have an Angular web application called "my-app".
I created a project on Google Firebase and called it "my-app" as well.
I deployed the Angular application to Firebase project "my-app". As a result, a site "my-app-*****" appeared. My app was accessible on "my-app-*****.web.app" address.
Then I created the second site in Hosting of the same project. I called it "my-app-dev". It got an address but was empty because nothing was deployed yet.
I followed instructions from google: https://firebase.google.com/docs/hosting/multisites
And even one question on StackOverflow: Firebase hosting deploy to other site
I added targets and modified firebase.json. In the result, they looked like that:
firebase.json file content:
"hosting": [
{
"target": "prod",
"public": "www",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
{
"target": "dev",
"public": "www",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
]
}
.firebaserc file content:
{
"projects": {
"default": "my-app-*****"
},
"targets": {
"my-app-*****": {
"hosting": {
"dev": [
"my-app-dev"
],
"prod": [
"my-app-*****"
]
}
}
}
}
But I faced an error when I executed command firebase deploy --only hosting:dev
However, when I executed command firebase deploy --only hosting:prod, everything was deployed without errors.
As a result, I am able to deploy my project to "my-app-*****" site, but I could not deploy my project to "my-app-dev" site. I want both sites to use same built files, that is why "public" was pointing to the same directory "www". Both sites located in the same Hosting of "my-app" project on Google Firebase.
Can someone please help me and explain what have I done wrong?
I have two firebase projects: myapp for prod, and myapp-dev for dev environment.
I first used the firebase cli to init my project with "myapp" and so all the files were generated with this, including the hosting resource myapp (so I can deploy my app to myapp.web.app).
Then I have added a second firebase project ("myapp-dev"). I run those
firebase use --add myapp-dev # I have selected the right myapp-dev firebase project and set `dev` as short name
firebase target:apply hosting myapp-dev myapp # note here that I also use name "myapp" as resource
I have manually changed my .firebasesrc because I want the dev project to be default...
So my .firebasesrc looks like this
{
"projects": {
"default": "myapp-dev",
"prod": "myapp"
},
"targets": {
"myapp": {
"hosting": {
"myapp": [
"myapp"
]
}
},
"myapp-dev": {
"hosting": {
"myapp": [
"myapp"
]
}
}
}
}
and firebase.json
{
"hosting": [
{
"target": "myapp",
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
],
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
}
}
Now when I ran those lines, the webapp got deployed to the prod env, the functions to the dev env...
firebase use myapp-dev
firebase deploy
EDIT
Running firebase target:apply hosting myapp myapp-dev helped !
In my case I had the same app deploying to 2 different environments (development and production). The documentation is not very clear on this scenario, took some playing around to get the right config.
.firebaserc
{
"projects": {
"production": "myapp-prod",
"development": "myapp-dev"
},
"targets": {
"myapp-prod": {
"hosting": {
"myapp": [
"site-name-prod"
]
}
},
"myapp-dev": {
"hosting": {
"myapp": [
"site-name-dev"
]
}
}
}
}
firebase.json
{
"hosting": [{
"target": "myapp",
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
}]
}
To deploy to production run
firebase use production
firebase deploy
To deploy to development
firebase use development
firebase deploy
When you run firebase deploy in the project, it uses the target specified in the hosting section on the firebase.json to deploy to the site name specified in the hosting section of the target in the .firebaserc
I think your config should be something like this.
file .firebasesrc
"targets": {
"myapp-dev": {
"hosting": {
"myapp-dev": [
"myapp-dev"
],
"myapp": [
"myapp"
]
}
}
}
file firebase.json:
"hosting": [
{
"target": "myapp-dev",
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
{
"target": "myapp",
"public": "dist/myapp", /* folder */
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
]
and then deploy using target documentation
My domain seems to redirect to the index.html and all the sub-links just fine.
Problem is it won't redirect to the api rule "source": "/api/**"
I've checked the API manually using the whole firebase url (no custom domain) and it works.
How can I get both domain.com/somelink and domain.com/api/somelink to work in union?
Here's the configuration.
firebase.json
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/api/**",
"function": "api"
},
{
"source": "**",
"destination": "/index.html"
}
]
},
"storage": {
"rules": "storage.rules"
}
}
As noted here https://stackoverflow.com/questions/44959652/firebase-hosting-with-dynamic-cloud-functions-rewrites/45224176#45224176
Create a main app which hosts all other top-level functions.
const funtions = require('firebase-functions');
const express = require('express');
const app = express();
app.get('/users/:userId/:userData/json', (req, res) => {
// Do App stuff here
}
// A couple more app.get in the same format
// Create "main" function to host all other top-level functions
const main = express();
main.use('/api', app);
exports.main = functions.https.onRequest(main);
firebase.json
{
"source": "/api/**", // "**" ensures we include paths such as "/api/users/:userId"
"function": "main"
}
Use the main hook.
const hooks = express();
main.use('/hooks/, hooks);