Farhan Yousaf
Farhan Yousaf

Reputation: 7

I Cannot find the solution for Firebase Storage Rules

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

Answers (1)

Bistru
Bistru

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

Related Questions