I am trying to upload a profile photo as a logged in user with the following however I get error
E/flutter (32619): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: [firebase_storage/unauthorized] User is not authorized to perform the desired action.
My code
User? user = await authenticationService.getCurrentUser();
// Create a Reference to the file
Reference ref =
FirebaseStorage.instance.ref().child(user!.uid).child('/profile.jpg');
final metadata = SettableMetadata(
contentType: 'image/jpeg',
customMetadata: {'picked-file-path': s!.path});
UploadTask uploadTask = ref.putFile(File(s.path), metadata);
var result = await uploadTask;
print(result);
My rule
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId
&& request.resource.contentType.matches('image/. ');
}
}
}
What am I missing here ?
CodePudding user response:
I understand that you want to upload a file to the following reference
FirebaseStorage.instance.ref().child(user!.uid).child('/profile.jpg');
and check, in the security rules, that the id of the user executing the upload corresponds to the value of user!.uid
.
In your security rules, you have a check as request.auth.uid == userId
but nowhere in the rules you define what is userId
. You need to use a wildcard, as follows:
service firebase.storage {
// The {bucket} wildcard indicates we match files in all Cloud Storage buckets
match /b/{bucket}/o {
match /{userId}/{imageId} {
allow read;
allow write: if request.auth.uid == userId
&& request.resource.contentType.matches('image/. ');
}
}
}
If you only upload images named profile.jpg
in this "folder", you could add a check like imageId == 'profile.jpg'
but you could also define the path as:
match /{userId}/profile.jpg {
allow read;
allow write: if request.auth.uid == userId
&& request.resource.contentType.matches('image/. ');
}