I'm using Next.js and am struggling to get firebase storage images to render on screen as they keep coming back as 403 errors.
I upload an image to storage when adding a document to firestore with a url nested in it then use that url to get the image
This is my Next Image tag with recipe.main_image.url == https://storage.googleapis.com/chairy-cooks.appspot.com/recipes/0O3Oycow4lJvyhDbwN0j/main_image/190524-classic-american-cheeseburger-ew-207p.png
And recipe.main_image.name == the name of the photo in firebase storage.
<Image
alt={recipe.main_image.name}
src={recipe.main_image.url}
width={650}
height={650}
/>
The alt tag comes back as the right thing (image name in firebase storage) so I know the image is getting sent back but for some reason I'm unauthorised I've tried multiple fixes including changing firebase rules to
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
AND
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
But neither change the outcome I've also set my next config up so I'm getting firebase storage
images: {
domains: ['images.ctfassets.net', 'storage.googleapis.com'],
},
CodePudding user response:
If the images will be served to the public, then i would suggest to grant public access to the image. Cloud Storage for Firebase is backed by Google Cloud Storage. You can make individual objects publicly readable or make the bucket publicly readable.
or better yet, generate signed URLs, this way you can grant limited time access to an object. If you're working with Javascript then you may take a look at this sample code on how to generate a signed URL.
/**
* TODO(developer): Uncomment the following lines before running the sample.
* Note: when creating a signed URL, unless running in a GCP environment,
* a service account must be used for authorization.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';
// The full path of your file inside the GCS bucket, e.g. 'yourFile.jpg' or 'folder1/folder2/yourFile.jpg'
// const fileName = 'your-file-name';
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function generateV4ReadSignedUrl() {
// These options will allow temporary read access to the file
const options = {
version: 'v4',
action: 'read',
expires: Date.now() 15 * 60 * 1000, // 15 minutes
};
// Get a v4 signed URL for reading the file
const [url] = await storage
.bucket(bucketName)
.file(fileName)
.getSignedUrl(options);
console.log('Generated GET signed URL:');
console.log(url);
console.log('You can use this URL with any user agent, for example:');
console.log(`curl '${url}'`);
}
generateV4ReadSignedUrl().catch(console.error);
You may visit this documentation for more information.