NGSW caching Firebase Storage - firebase

Problem:
Unable to handle Firebase Storage urls in Angular6 service worker (presumably due to CORS).
firebase.json
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [ {
"source" : "**/*.#(eot|otf|ttf|ttc|woff|font.css)",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
}, {
"source" : "**/*.#(jpg|jpeg|gif|png)",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=7200"
} ]
}, {
"source" : "404.html",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=300"
} ]
} ]
}
}
ngsw-conf.json
{
"index": "/index.html",
"assetGroups": [{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/apple-touch-icon-precomposed.png",
"/apple-touch-icon.png",
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**"
],
"urls": [
"https://fonts.googleapis.com/**",
"https://firebasestorage.googleapis.com/**"
]
}
}],
"dataGroups": [{
"name": "api-performance",
"urls": [
"/some_route"
],
"cacheConfig": {
"strategy": "performance",
"maxSize": 100,
"maxAge": "3d"
}
}
]
}
All files were uploaded to the Firebase Storage with following metadata:
{
cacheControl: 'public,max-age=36000',
contentType: 'image/jpeg'
}
When I load the app in Chrome or Opera, the app renders OK but I get error message 'Failed to load some_firebase_storage_download_link : No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin my_app_domain is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.' and when I reload the app, no Firebase Storage resources are loaded.
When I load the app in Safari or Edge the app does not render at all and I get multiple console errors 'Failed to load resource'.
The app is being rendered and cached in Firefox without any issue.
When I omit the Firebase Storage and use only resources in Firebase Hosting, then the app is cached errorless in all browsers.
I have searched for setting the request's mode to 'no-cors', but failed to reach any resolution regarding my issue.
UPDATE
This might be caused by interference of NGSW and Firebase Firestore persistence handler (ie.: firebase.firestore().enablePersistence(); ). I am not sure how exactly Firebase Firestore persistence works, but when I initialise the app without Firestore persistence, then I am able to cache dynamic links from Firebase Storage. That is no use to me as I need both db and storage available at the same time.

Related

Firebase Hosting "rewrites" to Access Next.js App on Google Cloud Run

We're using Firebase Hosting. We have a Next.js app, called "knowledge", deployed on Google Cloud Run in the same GCP project. We followed the instructions in the Firebase documentation. Our firebase.json is as follows:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"hosting": {
"public": "build",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "/knowledge{,/**}",
"run": {
"serviceId": "knowledge",
"region": "us-central1"
}
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}
We want every request to "/knowledge{,/**}" for server-side rendering through our Next.js app on Cloud Run. When we open any of these pages, it loaded, but it does not load any of the static file, showing many errors like the following in the console:
Uncaught SyntaxError: Unexpected token '<' (at webpack-df4cf1c8d23aa877.js:1:1)
framework-81da43a8dcd978d9.js:1
Our next.config.js is as follows:
module.exports = {
async rewrite() {
return [
{
source: "/knowledge",
destination: "/",
},
];
},
images: {
domains: ["firebasestorage.googleapis.com"],
},
};
Static files will be under /_next/, so add '/path*'.
module.exports = {
async rewrite() {
return [
{
source: "/knowledge",
destination: "/",
},
{
source: "/knowledge/:path*",
destination: "/:path*",
},
];
},
images: {
domains: ["firebasestorage.googleapis.com"],
},
};

Firebase "Access to Font" error

This may be an oversight but I'm using firebase and set up the firebase.json file which is a mixture of auto-generation and copying the headers block from Firebase's documentation. The issue is, my fonts refuse to allow me access even though my file looks like this:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{
"source" : "**/*.#(eot|otf|ttf|ttc|woff)",
"headers" : [{
"key" : "Access-Control-Allow-Origin",
"value" : "*"
}]
}, {
"source" : "**/*.#(jpg|jpeg|gif|png|svg)",
"headers" : [{
"key" : "Cache-Control",
"value" : "max-age=7200"
}]
}]
},
"storage": {
"rules": "storage.rules"
}
}
This is the CORS error I'm getting:
Access to Font {Firebase font url}. {Firebase font url} from origin {Firebase project url} has been blocked by CORS policy. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin {Firebase project url} is therefore not allowed access.
Side note: I have an images folder in which I am able to load those just fine. Is there something about fonts that require more attention?
Firebase rolled out a new feature/tool that forces users to update the CORS settings for Google Storage. I found the answer on this StackOverflow question.
Firebase Storage and Access-Control-Allow-Origin

Firebase Hosting: Caching the underlying file from a re-written route

Problem:
Unable to apply caching headers to re-written routes (i.e. /bla -> /index.html).
Firebase documentation clearly states that the headers are applied when the 'source' glob pattern matches the original request.
Can anyone help with a workaround / solution to this?
Code:
Note: The headers directive for the 'index.html' source does not work unless the user directly hits /index.html, but is kept in the code to better articulate the issue.
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "build",
"rewrites": [
{
"source" : "**",
"destination": "/index.html"
}
],
"headers": [
{
"source": "index.html",
"headers": [
{
"key" : "Cache-Control",
"value" : "max-age=0"
}
]
},
{
"source": "**/*.#(js|css)",
"headers": [
{
"key" : "Cache-Control",
"value" : "max-age=31536000"
}
]
}
]
}
}

Access-Control-Allow-Origin requesting storage file

I receive error
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://MY-Firebase-APP.Firebaseapp.com' is therefore not allowed access.
when accessing a json file from my Firebase storage. Here is the rules for the storage-
service firebase.storage {
service firebase.storage {
match /b/paystumped.appspot.com/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
The app is hosted by Firebase as well. Here is the firebase.json I am using when I run 'firebase deploy'
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"headers": [
{
"source": "**/*",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
},
{
"source": "**/*.#(jpg|jpeg|gif|png)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=7200"
}
]
},
{
"source": "404.html",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=300"
}
]
}
],
"cleanUrls": true,
"trailingSlash": false
}
}
I am sure there is some trivial CORS setup to do to make this work.
After reading up on CORS and understanding how this should work I found the desired answer here.
https://stackoverflow.com/a/37765371/4360863
The firebase storage policy is configured by a utility provided by google.

Access-Control-Allow-Origin added to firebase.json but missing from the file response header

Below is my simple firebase.json. If I read the docs right it should tag all files with 'Access-Control-Allow-Origin'. Unfortunately none of the files are being tagged resulting in the error:
Imported resource from origin 'https://gaspush.firebaseapp.com' has
been blocked from loading by Cross-Origin Resource Sharing policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
Could someone take a look and let me know how to properly allow all files to all endpoints?
{
"firebase": "gaspush",
"headers": [ {
"source" : “**”,
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
} ],
"public": ".",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
This is maybe no longer relevant to the original question, but I ran into a similar issue with the new version of Firebase. I had accidentally placed "headers" section outside of the "hosting" key.
The below snippet worked for me.
"hosting": {
"public": ".",
"headers": [ {
"source" : "**",
"headers" : [{
"key" : "Access-Control-Allow-Origin",
"value" : "*"
}]
}]
}

Resources