I have been trying to upload an image directly from my react spa to my firebase bucket but I can't configure the cors properly.
I set the cors configuration in muy bucket using the GCP console, as:
[
{
"origin": ["http://localhost:3000"],
"method": ["PUT"],
"responseHeader": [
"Content-Type",
"Access-Control-Allow-Origin",
"x-goog-resumable"],
"maxAgeSeconds": 3600
}
]
but it doesn't works in the browser, instead in postman it works as expected.
My app implementation works as follows:
First I generate the presigned url in my node api as:
const admin = require('firebase-admin');
const uuid = require('uuid');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
storageBucket: "<BUCKET-NAME>"
});
var bucket = admin.storage().bucket();
const generateSignedUrl = async (userId) => {
const key = `${userId}/${uuid.v1()}.jpeg`;
const options = {
version: 'v4',
action: 'write',
expires: Date.now() + 5*60 * 1000,
contentType: 'image/jpeg'
};
const [ url ] = await bucket
.file(key)
.getSignedUrl(options);
return [url, key];
};
Then in the spa I use axios to perform the put request in order to upload the file using the presignedUrl provided from my node api.
const config = {
headers: { 'Content-Type': 'application/octet-stream' }
};
await axios.put(presignedUrl, file, config);
But the CORS error appears:
Access to XMLHttpRequest at 'https://storage.googleapis.com/...' from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Finaly I resolved my issue, I post the answer here, maybe it could help someone else. I had two issues.
delete axios.defaults.headers.common["x-auth-token"];
No 'Access-Control-Allow-Origin' header is present..
error always appeared. Once I figured out the correclty error thanks to firefox, I change the options for signedUrl generation as: const options = {
version: 'v4',
action: 'write',
expires: Date.now() + 5*60 * 1000,
contentType: `image/${type}`
};
where type is the type of the image to upload, provided from the spa.
The cors configuration works as expected.
[{
"origin": ["http://localhost:3000"],
"method": ["PUT"],
"responseHeader": [
"Content-Type"
],
"maxAgeSeconds": 3600
}]
To make changes to your selected bucket, you can use this command:
gcloud storage buckets update gs://{BUCKET_NAME} --cors-file={CORS_FILE}