Reputation: 9929
I'm very new to Firebase so hopefully this is a simple fix ...
I have a couple basic storage rules setup just for testing, however it would seem that the rule for limiting the upload file size is not being honoured:
Storage Rules
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read: if request.auth != null;
}
match /photos/{image} {
allow write: if request.resource.size < 3 * 1024 * 1024 && request.auth != null;
}
}
}
I have followed the rule code from here https://firebase.google.com/docs/storage/security/start
I have been able to upload a file over 5mb. Firebase Storage reports file size of 5.33mb, more than the supposed 3mb limit.
To check that the rule is recognised (that I have the correct path structure) I changed it to only allow a file its name was over 3 characters - I tried to upload a file with a longer name and it didn't permit this as expected.
Edit
Current app side code to upload to Storage (very basic 'messy' setup!). Basically I have a image file picker that returns to onActivityResult
:
private static final String PHOTO_URLS = "photo_links";
private static final String PHOTOS_DATA = "photos";
private FirebaseDatabase firebaseDatabase;
private DatabaseReference photosDatabaseReference;
private FirebaseStorage firebaseStorage;
private StorageReference storageReference;
private OnSuccessListener<UploadTask.TaskSnapshot> uploadSuccessListener;
private OnFailureListener uploadFailureListener;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firebaseDatabase = FirebaseDatabase.getInstance();
photosDatabaseReference = firebaseDatabase.getReference().child(PHOTO_URLS);
firebaseStorage = FirebaseStorage.getInstance();
storageReference = firebaseStorage.getReference().child(PHOTOS_DATA);
uploadSuccessListener = taskSnapshot -> photosDatabaseReference.push().setValue(new PhotoEntry(taskSnapshot.getDownloadUrl().toString()));
uploadFailureListener = Exception::printStackTrace;
}
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK){
switch(requestCode){
case REQUEST_CODE_PHOTO:
uploadToFirebase(data.getData());
break;
case REQUEST_CODE_AUTH:
// stuff to handle Auth ...
default: break;
}
} else if (resultCode == RESULT_CANCELED) {
makeText(this, "Operation cancelled", LENGTH_SHORT).show();
if(requestCode == REQUEST_CODE_AUTH) finish();
}
}
private void uploadToFirebase(Uri imageUri) {
StorageReference reference = storageReference.child(imageUri.getLastPathSegment());
reference.putFile(imageUri).addOnSuccessListener(uploadSuccessListener).addOnFailureListener(uploadFailureListener);
}
@Override protected void onDestroy() {
super.onDestroy();
uploadSuccessListener = null;
uploadFailureListener = null;
}
Where am I going wrong?
Upvotes: 1
Views: 3049
Reputation: 15963
Per the docs, "If multiple rules match a file, the result is the OR
of the result of all rules evaluations. That is, if any rule the file matches evalutes to true
, the result is true
."
Stated another way, your two rules are in conflict: one allows anything anywhere, so long as the request is authenticated; while another requires a file size limit. Unfortunately, due to the above, this means that files can be uploaded regardless of the restriction, since a rule is effectively "overriding" your deeper rule.
You likely want rules that instead look like:
service firebase.storage {
match /b/{bucket}/o {
match /anotherPath/{allSubPaths=**} {
// Only use named paths
allow write: if request.auth != null;
}
match /{allOtherPaths}/{allSubPaths=**} {
// Or explicitly call out the path you want to avoid in the condition
allow write: if allOtherPaths!= "photos" && request.auth != null;
}
match /photos/{image} {
allow write: if request.resource.size < 3 * 1024 * 1024 && request.auth != null;
}
}
}
Upvotes: 1