I've deployed a next.js app to Google Cloud and am using Functions and Hosting.
I recently tried to move everything to northamerica-northeast1 region. I re-deployed all the functions placing .region("northamerica-northeast1") at the start of all my Functions as shown here. This successfully updated the location of all my functions.
However, I also use a function to serve my next.js app:
const server = functions.https
.onRequest((request, response) => {
return app.prepare().then(() => handle(request, response));
});
And I re-write all URLs to this function:
"hosting": {
"target": "webapp",
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"function": "nextjs-server"
}
]
},
This is all standard next.js on Google Cloud stuff and I've been doing it for 2+ years. However, when I moved the function to the new region using this:
const server = functions
.region("northamerica-northeast1")
.https
.onRequest((request, response) => {
return app.prepare().then(() => handle(request, response));
});
It appears the re-write no longer works. The function was updated, but when I visit the site, I get a 404. Then, when I move the function back to the default region (by removing the .region()) it works again fine.
I tried on 3 current projects, same thing.
Finally, I tried creating a brand-new, fresh project and deployed to the northamerica-northeast region (as before) and pushed the functions live with the region code in it...so my project never was hosted anywhere except northamerica-northeast1 and it still failed. However, by removing the region, the re-writes start working fine again and I can see the site. This is even though the entire rest of the site is in the northamerica-northeast1 region and just this one server function moved to the default region.
I believe this is a bug in rewrites on google cloud? Or is there something I'm missing or some doc somewhere that says re-writes are unavailable in this region?
If you want to use Hosting and Cloud Functions together, the Functions be located in us-central1.
Firebase Hosting supports Cloud Functions in us-central1 only.
Serve dynamic content and host microservices with Cloud Functions
Related
I deployed a new version of a web app that included some new Firebase functions. The new Firebase functions were inaccessible upon deployment.
I was able to find the root cause by familiarity with Firebase's configuration: the function requests were intended to route through the main app domain, and be redirected on the Firebase server to their final destination. (This should have been set up with Firebase's 'rewrites' section of firebase.json, but wasn't.)
A partial view of my rewrites section of firebase.json:
"rewrites": [
{
"source": "/getPlaces",
"function": "getPlaces"
},
...
{
"source": "**",
"destination": "/index.html"
}
]
In plain English, this says, "Firebase server: every time you get a request routing to https://my.app/getPlaces, I want you to not route to that address within my app; I want to invoke my Cloud function instead. Otherwise, route normally."
Yet when I look at the Functions tab of my Firebase console, all I see is this:
Under 'Request', it says https://us-central1-my-app.cloudfunctions.net/getPlaces. That gives me just one of the ways to access my function; the other is https://my.app/getPlaces, as defined in rewrites. I need to know all of the addresses that Firebase will respond to, not just the default one using cloudfunctions.net.
Is it possible to see the entire configuration for the deployed Firebase functions anywhere in the web UI, ie console.firebase.com or console.cloud.google.com, where redirects from rewrites like this can be seen?
I have a website that I'm already running on firebase hosting using a google domain. I would like to now show all calls to my firebase function being made through a url such as api.mydomain.com, instead of the default firebase domain. How is it that I may be able to do this?
I read the firebase tutorial on hosting cloud functions, and I also came across this article on creating multiple sites. So could someone please tell how is it that I can set up the workflow such that my site is still running at mydomain.com, but my APIs are now being called through api.mydomain.com? What would be the target name for
If possible, I Would like all requests to be shown as requests to api.mydomain.com, and not to api.mydomain.com/endpoint - so that what endpoint is being hit is also hidden from public
Sorry, I am new to this.
Let's say your main project has an ID of example-app. To serve requests as api.mydomain.com, you would have to use a Cloud Function that makes use of express (or some other similar route handler).
Create the secondary site for your project using the Firebase CLI, (with an id of example-app-api, example-api, etc.)
firebase hosting:sites:create example-app-api
Connect your hosting targets to your resources
firebase target:apply hosting app example-app
firebase target:apply hosting api example-app-api
Modify your firebase.json file to suit the targets above.
{
"hosting": [
{
// app is linked to example-app, served as mydomain.com
"target": "app",
// contents of this folder are deployed to the site "example-app"
"public": "public",
// ... other settings ...
},
{
// api is linked to example-app-api, served as api.mydomain.com
"target": "api",
// Contents of this folder are deployed to the site "example-app-api"
// Any file here will be returned instead of calling your Cloud Function.
// Recommended contents:
// - favicon.ico (website icon for bookmarks, links, etc)
// - robots.txt (instructions for bots and scrapers)
// Optional contents:
// - service-worker.js (empty file, used to prevent triggering cloud function)
// - humans.txt (details about who you/your company are & how to report bugs)
"public": "api-static-resources",
// ... other settings ...
"rewrites": [
{
// redirect all calls to the function called "api"
"source": "**",
"function": "api"
}
]
}
]
}
Deploy the api hosting config using the Firebase CLI
firebase deploy --only hosting:api
Open Hosting Settings for your project, click "View" for example-app-api then click "Custom Domain" following these instructions.
You should now be able to trigger your Cloud Function by calling it at api.mydomain.com.
api.mydomain.com/getPost?id=someId
api.mydomain.com/favicon.ico
api.mydomain.com/robots.txt
I have an api set up on Google Cloud Functions (https://europe-west1-myproject-name.cloudfunctions.net/api/v1/ical.ics).
This works well, but I wish to set up a "friendly" domain name for the api. :)
According to Googles documentation this is seems easy, but it does not seem to work for cloud functions outside the USA, eg. europe-west1.
I have updated the firebase.json file with the below code according to documentation.
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/api/**",
"function": "api"
},
{
"source": "**",
"destination": "/index.html"
}
]
}
When accessing https://myproject-name.web.app/api/v1/ical.ics
I get redirected to https://us-central1-myproject-name.cloudfunctions.net/api/api/v1/cal.ics with error 403 and the below error message.
Error: Forbidden
Your client does not have permission to get URL /api/api/ical.ics from this server.
I must be overlooking something really basic here, since this seems like a really easy operation? :)
Kind regards
/K
As stated in the documentation (see blue text block):
If you are using HTTP functions to serve dynamic content for Firebase
Hosting, you must use us-central1.
You will also find a similar warning in the doc you refer to in your question about "Serve dynamic content and host microservices with Cloud Functions" (See blue text block as well):
Firebase Hosting supports Cloud Functions in us-central1 only.
It is not completely the answer you are looking for since it is not possible with Firebase Hosting.
But it is possible to get a custom domain in front of your cloud functions hosted in EU by using Cloud Run.
I followed this guide:
https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-functions
And after that i added the custom domain under the Manage custom domains on Cloud Run.
I have set up rewrites for named functions in firebase.json but still firebase.functions().httpsCallable() envokes [my-server].cloudfunctions.net/[function-name] instead of [my-server].com/
I am upgrading a current project that has been working fine with cloudfunctions.net, but I would like to limit the domain names being called because of some firewalls blocking that domain.
Reading the guide if thought this addition in firebase.json would be sufficient:
"rewrites": [
{
"source": "/getResponse",
"function": "getResponse"
}]
and then calling the function from my app with:
firebase.functions().httpsCallable('getResponse')
...But that envokes [my-server].cloudfunctions.net/getResponse instead of [my-server].com/getResponse
Opening [my-server].com/getResponse in my browser works, so I figure, there is some sort of explicit setting on firebase.functions() where I can force it to use custom domain?
Thanks you for any help
There is no way to configure the Firebase client SDK for callable functions to invoke anything other than the default URL for the function. If this is somehow important to you, you are free to file a feature request.
For firebase tools 6.9.2:
When using firebase emulators:start --only functions, hosting where the functions are invoked via a hosting rewrite rule, the functions are invoked with different request url path prefixes than if the functions were deployed to the cloud. For example given a firebase.json hosting snippet such as:
{
"target": "myapi",
"public": "./dist/hosting/myapi",
"rewrites": [{
"source": "/api/myapi/*",
"function": "myapi"
}
]
},
When deployed to firebase, the myapi function will be called with a request url that starts with:
/api/myapi/
but if run in the emulator it ends up looking like:
/[firebase-project-id]/[firebase-region]/myapi/api/myapi/
This doesn't make a difference if the function doesn't look at the request path but in my case, the function is a handler for an express (koa) handler with routes so knowing the base path is important.
I've looked to see if anything is available in process.env but only the GCLOUD_PROJECT name and a few FIREBASE_CONFIG params are there.
I could not find any documentation on more advanced control of the rewrite to a function in firebase.json.
I can work around it in testing by setting an environment variable to match the prefix the functions are running at locally and taking it into account during request handling. Unfortunately the request url prefix is not available until after the emulators are started and the function urls are logged.
I am hoping to find a better solution for testing.
This turned out to be a bug and is was resolved for my case in firebase-tools 6.10.0.
https://github.com/firebase/firebase-tools/issues/1279
This related issue was also opened:
https://github.com/firebase/firebase-tools/issues/1312