【问题标题】:Firebase Storage RulesFirebase 存储规则
【发布时间】:2017-08-11 04:08:32
【问题描述】:

我是 Firebase 的新手,所以希望这是一个简单的解决方法...

我有几个基本的存储规则设置只是为了测试,但是限制上传文件大小的规则似乎没有得到遵守:

存储规则

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;
    }
  }
}

我已经按照这里的规则代码https://firebase.google.com/docs/storage/security/start

我已经能够上传超过 5mb 的文件。 Firebase 存储报告文件大小为 5.33mb,超过了假设的 3mb 限制。

为了检查规则是否被识别(我的路径结构正确),我将其更改为只允许名称超过 3 个字符的文件 - 我尝试上传名称较长的文件,但它不允许这符合预期。

编辑

要上传到存储的当前应用端代码(非常基本的“混乱”设置!)。基本上我有一个返回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;
    }

我哪里错了?

【问题讨论】:

  • 请贴出上传文件的代码。
  • @qbix 嗨,我添加了一些我用来执行任务的相关代码 - 希望它会指出我出错的地方。
  • 我无法重现您的结果,但没有复制您代码的所有细节。也许在uploadSuccessListener 中添加一条日志消息,输出taskSnapshot.getBytesTransferred() 以确认上传文件的大小。
  • @qbix 嗨,我想我已经解决了这个问题......从发布新规则到为个人用户实际执行这些规则似乎不是即时的,即如果设置了 3mb 规则,它可能允许上传3mb 一段时间或直到用户注销和登录?我之所以问,是因为我在退出并再次登录后上传时收到 403 错误(拒绝存储权限),这意味着该规则得到了正确遵守?
  • user guide 包含以下内容:规则会立即上传到 Cloud Storage 服务器,但最多可能需要五分钟才能生效。对于我的测试规则更改在几秒钟内可见。也许位置是一个因素;我在加利福尼亚。

标签: android firebase firebase-security firebase-storage


【解决方案1】:

Per the docs, "如果多个规则匹配一个文件,结果是所有规则评估结果的OR。也就是说,如果文件匹配的任何规则评估为true,结果是@ 987654324@。”

换一种说法,你的两条规则是冲突的:一条允许任何地方的任何东西,只要请求经过身份验证;而另一个需要文件大小限制。不幸的是,由于上述原因,这意味着无论限制如何都可以上传文件,因为规则实际上“覆盖”了您更深层次的规则。

您可能希望规则看起来像:

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;
    }
  }
} 

【讨论】:

  • OP 的规则只有一个allow write 的规则。我对 ORed 的规则感到困惑。 match /{allPaths=**} 是否有隐含的 allow write;?我问是因为在我运行的测试中,OP 的规则有效。如果文件大小超过限制,他们会拒绝写入。
  • 哇,完全错过了那个细节......是的,如果它们属于同一类型(所有读取、写入等),它们只有 ORed。我会尝试重现。
  • 嗨,谢谢你的帖子——正如@qbix 指出的我没有冲突——我一开始是这样做的,但很快意识到级联规则冲突并更改为发布,所以我很茫然 - 我已经更新以包含上传文件的非常基本的代码。我看到它的方式是我对经过身份验证的用户具有全局读取权限,但在 /photos/ 路径上的写入受到限制。
猜你喜欢
  • 2021-01-03
  • 2020-11-28
  • 2017-06-16
  • 1970-01-01
  • 2021-09-29
  • 2018-08-03
  • 2017-01-25
  • 2020-07-03
相关资源
最近更新 更多