Reputation: 2017
I have two image files uploaded to firebase storage:
capsule house.jpg was uploaded through the UI (clicking the Upload file button).
upload_64e8fd... was uploading from my backend server (node.js) using this:
const bucket = fbAdmin.storage().bucket('gs://assertivesolutions2.appspot.com');
const result = await bucket.upload(files.image.path);
capsule house.jps is recognized as a jpeg and a link to it is supplied in the right hand margin. If I click on it, I see my image in a new tab. You can see for yourself:
upload_64e8fd... is not recognized as any kind of image file and no link it provided.
The result returned on the backend is a huge json object with the following fields:
"selfLink": "https://www.googleapis.com/storage/v1/b/assertivesolutions2.appspot.com/o/upload_64e8fd09f787acfe2728ae73158e20ab"
"mediaLink": "https://storage.googleapis.com/download/storage/v1/b/assertivesolutions2.appspot.com/o/upload_64e8fd09f787acfe2728ae73158e20ab?generation=1590547279565389&alt=media"
The first one sends me to a page that says this:
{
"error": {
"code": 401,
"message": "Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.",
"errors": [
{
"message": "Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.",
"domain": "global",
"reason": "required",
"locationType": "header",
"location": "Authorization"
}
]
}
}
The second one gives me something similar:
Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.
The rules for my storage bucket are as follows:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
I'm allowing all reads and writes.
So why does it say I don't have access to see my image when it's uploaded through my backend server?
I'd also like to know why it doesn't recognize it as a jpeg when it's uploaded through my backend server, but it does when uploaded through the UI, but I'd like to focus on the access issue for this question.
Thanks.
Upvotes: 1
Views: 1345
Reputation: 41
You need to allow public read access
public String uploadImage(String name, String image) {
final byte[] bytes = Util.convertBase64ToByteArray(image);
final String imageExtension = Util.getImageExtensionFromBase64(image);
final String img = name+"."+imageExtension;
Storage storage = StorageOptions.getDefaultInstance().getService();
final BlobId blobId = BlobId.of(BUCKET_NAME, img);
final BlobInfo blobInfo = BlobInfo.newBuilder(blobId)
.setContentType("image/"+imageExtension)
.setAcl(new ArrayList<>(List.of(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)))) // allow read access
.build();
final Blob blob = storage.create(blobInfo, bytes);
return blob.getMediaLink();
}
Upvotes: 0
Reputation: 6959
The other answer helped me! I have no idea why the Console had me make those security rules if they won't apply...
Based on nodejs docs (and probably other languages) there is a simple way to make the file public during upload:
const result = await bucket.upload(files.image.path, {public: true});
This same option works for bucket.file().save()
and similar APIs.
Upvotes: 1
Reputation: 4670
By default, the files are uploaded as private, unless you change your bucket settings, as mentioned here. The below code is an example of how to change the visibility of your documents.
/**
* {@inheritdoc}
*/
public function setVisibility($path, $visibility)
{
$object = $this->getObject($path);
if ($visibility === AdapterInterface::VISIBILITY_PRIVATE) {
$object->acl()->delete('allUsers');
} elseif ($visibility === AdapterInterface::VISIBILITY_PUBLIC) {
$object->acl()->add('allUsers', Acl::ROLE_READER);
}
$normalised = $this->normaliseObject($object);
$normalised['visibility'] = $visibility;
return $normalised;
}
You can check how to set that via console, following the tutorial in the official documentation: Making data public
Besides that, as indicated in the comment by @FrankvanPuffelen, you won't have a generated URL for the file to be accessed. You can find more information about it here.
Let me know if the information helped you!
Upvotes: 1