Firebase存储规则

时间:2017-03-20 00:34:07

标签: android firebase firebase-security firebase-storage

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

我哪里错了?

1 个答案:

答案 0 :(得分:1)

Per the docs,&#34;如果多个规则与文件匹配,则结果为所有规则评估结果的OR。也就是说,如果文件将evalutes与true匹配,则结果为true。&#34;

换句话说,你的两个规则是冲突的:只要请求被认证,就可以在任何地方允许任何内容;而另一个需要文件大小限制。不幸的是,由于上述原因,这意味着无论限制如何都可以上传文件,因为规则实际上是有效的&#34;覆盖&#34;你的更深层次的规则。

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

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