I want to rewrites all URL end with "api/(funcName)" to call cloud function (funcName).
In firebase.json I set rewrites rules as follows.
"rewrites": [
{
"source": "api/:funcName",
"function": ":funcName"
},
{
"source": "**",
"destination": "/index.html"
}
]
but it's not working.
I got
Error: Forbidden
Your client does not have permission to get URL /:funcName/api/(funcName) from this server.
(funcName) is the real function name I don't want to show here.
Your rewrite should include the exact name of the function. The rewrite system doesn't support named wildcard routes like you use in Express. If you want to wildcard all URLs with a prefix, use the glob syntax supported by Firebase Hosting as described in the documentation.
{
"source": "api/**",
"function": "funcName"
},
Where "funcName" is the name of your function as exported by your code.
I'm not exactly sure how you got it to throw that error message, but from what I can quickly see the error message comes from Cloud Functions, or from something between Firebase Hosting and your Cloud Function.
Given where the error message comes from, Firebase Hosting won't be able to hide it for the response.
Related
I use firebase.json to rewrite any request to /index.html which have link to external css in the same directory.
firebase.json:
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
However, when I go to sub url like example.com/user, the index.html the linked css did not imported. And the script resource also did not imported, instead console spit this error:
failed to load module script: expected a javascript module script but the server responded with a mime type of "text/html"
I searching in firebase docs, and find the header config that
Applies a CORS header
I did not understand, is this what I need ?
Do I need to use absolute path instead ?
I only use firebase hosting not cloud function.
Any help would appreciated 🙏
I am following this
https://firebase.google.com/docs/hosting/functions (Use a Web Framework)
in order to rewrite a url in the form of http://<mycustom_domain>/<api_name> on Firebase hosting to the respective Cloud Functions that use Express(). The endpoint for the API is https://<google_cloud_function_url>/app/<api_name>
This rewrite works:
"rewrites": [ {
"source": "**",
"function": "app"
} ]
What I want to do is rewrite http://<mycustom_domain>/app/<api_name> to
https://<google_cloud_function_url>/app/<api_name>.
I have tried a few things such as
"rewrites": [ {
"source": "/app/**",
"function": "app"
} ]
In the hope that whatever path comes after /app is passed onto express as the API name but this does not work and express returns something like
Cannot GET /app/<api_name>
Any ideas how the rewrite should be written for this to work?
I currently have the following configuration:
// firebase.json
{
"hosting": [
{
"rewrites": [{
"source": "/articles{,/**}",
"destination": "/articles"
},
{
"source": "**",
"destination": "/index.html"
}]
}
]
}
If I go to mysite.com/articles/<articleID> I'm taken to mysite.com when I'd expect to be taken to mysite.com/articles. What am I doing incorrectly?
I'm following this documentation.
I was able to resolve the issue after taking the following steps:
Change my source from /articles{,/**} to /articles/**
Change my destination from articles to articles.html which is a valid local file
Realize that changes to firebase.json don't change the behavior of the Firebase Hosting emulator until it is restarted.
I believe there are two possible causes.
You have set hosting as an array instead of an object (although I am not completely sure if that is an issue)
Secondly, as you can see in the documentation you shared, just above the heading Direct requests to a function, it says that the destination file must exist and as mysite.com/articles doesn't evaluate to a local file, it is caught by the second rewrite rule and redirected to index.html.
I am setting up a redirect(rewrite) with my firebase hosting so that I can call an api that is running from google cloud run here.
I have tried changing the rewrite string from "/api/**" (should catch all things to page.com/api/** and send that to the function). deleted the index.html and swapped to "**" to capture ALL paths including index. Nothing has worked so far.
My hosting firebase.json is setup like so, is there something wrong with this?
{
"hosting": {
"public": "dist/public",
"ignore": ["firebase.json", "**.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"run": {
"serviceId": "next-js-base-api",
"region": "us-central1"
}
}
]
}
}
I also tried with normal redirects to another page, this does not work, what determines when the firebase.json settings begin to propagate and work?
Update
I tried running the hosting emulator and with a modified rewrite "source": "/api/**" which had the following results. Navigating to /api returns non crash (doesn't redirect) with output in browser of cannot GET /api navigating to api/wkapi (a sub directory that is caught by the api endpoint) returns an unexpected error in the browser and
Error: Unable to find a matching rewriter for {"source":"/api/**","run":{"serviceId":"next-js-base-api","region":"us-central1"}}
in the console.
Make sure to update to the latest version of your Firebase CLI by running:
npm install -g firebase-tools#latest
This will enable you to rewrite to cloud run instances as you are trying to do.
Actually, I ran this just now and, looking at the logs of the deployed cloud-run helloworld container, found that custom-domain/helloworld is actually mapping onto container-domain/helloworld instead of simply mapping to container-domain/. To fix this, I had to add an additional app.get rule to my original Node.js program:
app.get('/helloworld', (req, res) => {
And then calling custom-domain/helloworld worked.
If all the above answers don't help you, the fix that worked for me was:
Look in the public directory in your project that firebase hosting uses.
Delete the index.html file that firebase created when going through
the firebase init steps.
After deleting the generated index.html file, it was able to run my cloud run containers with rewrites.
In my case, the cause for this was misspelling function in the firebase.json file, i,e:
"rewrites": [
{
"source": "**",
"function": "ngssr" // I had spelled this as "functions" (extra s)
}
]
I have a Firebase hosted single page app.
I also have 3 Firebase functions (contact, plans, features) that the app and external sources make requests of.
My app has a custom domain, which I'd like to access my functions via.
This is my current firebase.json config
{
"hosting": {
"public": "www",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
So currently all traffic goes to my app and routing is handled via my SPA. Access to my functions currently has to be done via the cloudfunctions.net URL which isn't ideal.
How can I add URL rewrite entries to this config so that my functions are accessible via my custom domain and my single page app handles the rest of the routes?
I have tried the following for the features endpoint:
"rewrites": [
{
"source": "/features/**",
"function": "features"
},
{
"source": "!/features/**",
"destination": "/index.html"
}
]
Where in my functions index.js I have:
...
exports.plans = functions.https.onRequest(plansApi);
exports.features = functions.https.onRequest(featuresApi);
exports.contact = functions.https.onRequest(contactApi);
But I receive 404 Cannot GET /features/123 as the response?
A few things:
Make sure that your featuresApi handler is matching for the full URL path (e.g. /features/123 not /123). Firebase Hosting forwards the full path to the function, not just the ** part.
Rewrites are resolved in order, so there's no need to do !/features/** for your second rewrite source. ** should be fine since if it matches /features/** it will already match the first rewrite and resolve to the function.
Based on the error message, it seems likely that (1) is the culprit here.