Reputation: 7
My firebase Storage Rules:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**}{
allow read: if request.auth != null; }
match /UsersPosts/{userId}{
allow write: if request.auth.uid == userId;
allow read: if request.auth != null;
} } }
When I set these Rules I cannot Upload an image file or any other file to my Firebase storage in "UsersPosts/{UserId}" Bucket.
On the other hand When I use these rules, I can upload my file in UserPosts/{UserId} node or bucket.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**}{
allow read: if request.auth != null;
allow write: if request.auth != null;
}
match /UsersPosts/{userId}{
allow write: if request.auth.uid == userId;
allow read: if request.auth != null;
}
}
}
I want that only current user with same uid can access that Bucket. When I run it with play ground Rules every thing works fine. But when I run it through app in flutter These error shows up:
E/StorageException(21358): StorageException has occurred.
E/StorageException(21358): User does not have permission to access this object.
E/StorageException(21358): Code: -13021 HttpResult: 403
E/StorageException(21358): The server has terminated the upload session
E/StorageException(21358): Caused by: java.io.IOException: { "error": { "code": 403, "message": "Permission denied." }}
E/StorageException(21358): Object does not exist at location.
E/StorageException(21358): Code: -13010 HttpResult: 404
E/StorageException(21358): { "error": { "code": 404, "message": "Not Found." }}
E/StorageException(21358): java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
E/flutter (21358): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: PlatformException(download_error, Object does not exist at location., null, null)
E/flutter (21358): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:597:7)
E/flutter (21358): #1 MethodChannel._invokeMethod (package:flutter/src /services/platform_channel.dart:158:18)
E/flutter (21358): <asynchronous suspension>
E/flutter (21358): #2 StorageReference.getDownloadURL (package:firebase_storage/src/storage_reference.dart:142:12)
E/flutter (21358): <asynchronous suspension>
E/flutter (21358): #3 _AddStatusState.uploadPhoto (package:switchtofuture/MainPages/Upload/addStatuse.dart:474:26)
E/flutter (21358): <asynchronous suspension>
E/flutter (21358): #4 _AddStatusState.controllAndUploadData (package:switchtofuture/MainPages/Upload/addStatuse.dart:412:28)
This is My code where error Sends me:
Future<String> uploadPhoto(mImageFile) async {
StorageUploadTask mStorageUploadTask = storageReference
.child("UsersPosts/${Constants.myId}/_$postId.jpg/")
.putFile(mImageFile);
StorageTaskSnapshot storageTaskSnapshot =
await mStorageUploadTask.onComplete;
String downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();
return downloadUrl;
}
When I try to upload Without any security rules (like anyone can read and write), Everything works fine my File upload with this path on Firebase Storage as:
(UsersPosts>>egO4Fu2M64Svh0UUg19V7YcS0C13>>_4dec97f6-1e10-4005-8a9e-8512a7c5d434.jpg)
Post id genrated with this code "String postId = Uuid().v4();"
Here, egO4Fu2M64Svh0UUg19V7YcS0C13 is Constans.myId, $postId is 4dec97f6-1e10-4005-8a9e-8512a7c5d434)
I just want to secure MY database so no one can delete my main Bucket, I want my database to readable for every authenticate user but writable by only certian user with same uid how is currently signedIn.
I hope I have brought all info that will need to experts to find error. I am A student, not a professional. I searched over 3 hours in google, yt but did not find any solution. If I can not secure My every Bucket then what the point? My app security will be zero. :(
Upvotes: 0
Views: 477
Reputation: 1
You actually writing in UsersPosts/{userId}/{postId}
but your rules is matching only for UsersPosts/{userId}
.
You need to use a wildcard as
match /UsersPosts/{userId}/{postId} {
}
or a recursive wildcard, if you need recursive matches
match /UsersPosts/{userId}/{document=**} {
}
in order to match your path.
In the second example you provided, the path you're trying to access is matched and allowed by the first rule match /{allPaths=**}
, but it doesn't apply any restriction based on the userId.
More detailed info here Secure data in Cloud Firestore.
Upvotes: 0