Firebase URL rewriting to both functions and destinations - reactjs

I am building a React/Redux app and trying to rewrite to one Firebase function, with all other URLs rewriting to index.html.
Right now, I am only able to get a URL to rewrite to the function when I perform the "empty cache and hard reload" on my Chrome browser.
This is my firebase.json file.
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "build",
"rewrites": [
{
"source": "/Photos/**", "function": "getPhoto"
},
{
"source": "**", "destination": "/index.html"
}
]
}
}
For example, when I go to https://nameofmyapp.firebaseapp.com/Photos/2017/October/2/12345, I am routed to the root directory (index.html), when I expect to be directed to the getPhoto function.
The only time I am able to get to the "/Photos/**" rewrite URL is if I first enter the https://nameofmyapp.firebaseapp.com/Photos/2017/October/2/12345 URL in the browser, then perform a "Empty Cache and Hard Reload" in Chrome. This is the only time that the function is executed for me. (Not sure if this is related to the service-worker behavior?) Even so, on normal refresh at that URL, I end up back in index.html again.
Can anyone let me know what I am missing?

I've just posted an answer for a very similar problem
You need to change your "single app rewrite" :
{
"hosting": {
"public": "build",
"rewrites": [
{
"source": "/Photos/**", "function": "getPhoto"
},
{
"source": "!/Photos/**", "destination": "/index.html"
}
]
}
}
Instead of redirecting everything on index.html (as do " ** "), this rule redirect everything that is not in the Photos folder and subfolders.

Related

Deployed Firebase project is a blank page, despite firebase.json pointing to the build folder

when I try to deploy my react app to firebase, the url leads to a blank page (although the favicon is up).
After googling the problem the best post I could find suggested I make sure that the firebase.json file is pointing to my build folder, but it is.
And it is still not working.
And I do not know what to try next.
Any ideas?
My firebase.json for context:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
I found this on another post, but I waited to try it because it far from the ranked answer.
Worked for me tho:
https://stackoverflow.com/a/68506094/20063520

Next.js Firebase Hosting 404 error on all except index.html

I've built a nextjs app, with npm run build && npm run export and deployed to firebase using firebase deploy command. Prior to that, I've used firebase init in my project folder with just using the default options eg. not a single page application.
After I go and visit my project in firebase provided url however, I see the home page which is index.html, but whenever I use any other slug it throws a 404. Why this is happening ? I`ve included my firebase.json file, in case it might help.
firebase.json
"hosting": {
"public": "out",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
For everybody that wants to deploy a statically exported Next.js app to Firebase hosting:
You would have to add "cleanUrls": true to the hosting configuration in firebase.json like so:
"hosting": {
"public": "build",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
Without the "cleanUrls" configuration, the user would have to navigate to
https://example.com/login.html so that Next.js routes to the login page for example. With the parameter, a web request to https://example.com/login would work.
With the rules you have Firebase Hosting serves the exact file that the user requested.
To rewrite other/all URLs to your index.html, you'll need to add a rewrite rule to your firebase.json. A typical rewrite rule for single-page applications may look like this:
"hosting": {
// ...
// Serves index.html for requests to files or directories that do not exist
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
}
If anyone is still looking for this, this is what fixed it for me:
I used dynamicLinks as stated in the firebase hosting docs for the rewrites like so in my firebase.json file:
{
"hosting": {
"public": "out",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"rewrites": [
{
"source": "/**",
"dynamicLinks": true
}
]
}
}
This should allow dynamicLinks to start at ("https://CUSTOM_DOMAIN/{dynamicLink}").

Firebase SPA rewrite rules not redirecting to index.html

I just started to build a Single-Page App on Firebase Hosting using AngularJS framework. I have run firebase init and chosen to rewrite all urls to /index.html as shown below:
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
I have my partial view templates stored in the following folders:
public/templates/home/dashboard.html
public/templates/courses/default.html
My Angular routings are working correctly and have my public/index.html checks for authorized access, including those partial views, and redirect the user to login view if the user has not been authenticated.
However, when I try to paste the URL of my template HTML files directly onto the browser address bar, Firebase does not redirect it to /index.html:
http://localhost:5000/templates/home/dashboard.html
http://localhost:5000/templates/courses/default.html
All the above template files are loaded on the browser and viewable by any unauthorized users who know the URLs of these template files. I have tried to add the following rules to my firebase.json file but none of them work:
Test #1:
"rewrites": [
{
"source": "**",
"destination": "/index.html"
},
{
"source": "/templates/**/.*",
"destination": "/index.html"
}
]
Test #2:
"rewrites": [
{
"source": "**",
"destination": "/index.html"
},
{
"source": "/templates{,/**}",
"destination": "/index.html"
}
]
NOTE: I did restart firebase serve for every attempt, but I'm not sure if the cache will affect this type of testing. I also don't know how to clear the server cache either.
My questions are:
What is the correct way to write the url rewrite rule in order to redirect users to /index.html when direct accessing to these partial view templates?
If there is no way to prevent direct access to partial view templates through the Firebase url rewrite rules, is there any other way that I can prevent this for security purposes?
Firebase hosting will serve static content with priority above dynamic rewrites. See this hosting order.
If you don't want those views accessed directly, you could move them to a cloud function and setting up your hosting to reroute "templates" to serve that cloud function. Then you can configure your cloud function to provide/deny access as needed.
Use redirects instead of rewrites
"hosting": {
"redirects": [ {
"source": "/foo",
"destination": "/bar",
"type": 301
} ]
}
Add ** to source to append destination with additional URL string.
E.g.
"hosting": {
"redirects": [ {
"source": "/foo**",
"destination": "/bar",
"type": 301
} ]
}
Results in /foo?var=bar redirecting to /bar?var=bar
See Configure redirects for more info.

Not including old JS in Firebase hosting causes service worker white screen

The build process of create-react-app (yarn run build) deletes the old static JS file before building anew. When deployed to Firebase Hosting, the old JS files are not included and are no longer served.
However after visiting the old version the Service Worker (built by sw-precache and sw-precache-webpack-plugin, included by default in CRA) has cached the old HTML, which includes the old JS file, which is no longer served, so I get a white screen and an error in the console, which is only fixed by clearing cache and reloading.
Am I doing something wrong?
The issue was that my Cache-Control headers were too short, meaning that my JS file wasn't being cached for long enough, causing the browser to re-request it upon a reload and not find it until the Service Worker updates.
Resolution: have long Cache-Control headers
I resolved this slightly differently to Marks answer.
Within your firebase.json file you need to make sure the Service Worker and the index.html file aren't cached. For me it was the index.html being cached which was the main issue.
Webpack changes the chunks name with each build and removes the previous version from /build. Therefore when they don't get uploaded and your browser looks at the cached index.html file it causes the white screen and the error.
I ended up with the following in my firebase.json file. Hope that helps
{
"hosting": {
"public": "build",
"headers": [
{
"source": "/service-worker.js",
"headers": [
{
"key": "Cache-Control",
"value": "no-store"
}
]
},
{
"source": "/index.html",
"headers": [
{
"key": "Cache-Control",
"value": "no-store"
}
]
}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
],
"source": "functions"
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
}
}

Firebase Dynamic Hosting Rewrite the home page

I am using Firebase dynamic hosting and would like the home page on my website (https://website.com) to redirect to a cloud function while all other urls are directed to a React app.
I have tried this in Firebase.json. But it doesn't seem to work.
"rewrites": [
{ "source": "/", "function": "app"},
{ "source": "**", "function": "/index.html"}
]
Any ideas on what the problem is?
When you hit your website home page, firebase always tries to find the "index.html" file in your public directory. If it is found, your rewrite "is not executed". To avoid this, remove your "index.html" file (or just rename it), and the first rewrite will start working.
About the second rewrite, if you are trying to return a file of your public directory, the key of that object needs to be "destination", instead of "function".
Let's say that you rename your "index.html" file to "myApp.html". Your firebase.json file would be:
"rewrites": [
{ "source": "/", "function": "app"},
{ "source": "**", "destination": "/myApp.html"}
]

Resources