Firebase 存储规则奇怪的行为

Firebase Storage Rules strange behavior

基于documentation,Firebase Storage Rules version 2 可以编写细化操作。

A read operation can be broken into get and list. A write rule can be broken into create, update, and delete.

service firebase.storage {
  match /b/{bucket}/o {
    // A read rule can be divided into read and list rules
    match /images/{imageId} {
      // Applies to single document read requests
      allow get: if <condition>;
      // Applies to list and listAll requests (Rules Version 2)
      allow list: if <condition>;

    // A write rule can be divided into create, update, and delete rules
    match /images/{imageId} {
      // Applies to writes to nonexistent files
      allow create: if <condition>;

      // Applies to writes to existing files
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
 }
}

假设我有这样的规则:

rules_version = '2';
service firebase.storage {
    match /b/{bucket}/o {
        match /randomFiles {
            allow get, create: if true;
            allow list, update, delete: if false;
        }
    }
}

根据官方文档,使用这个规则我可以​​:

  1. 上传新文件,如果没有任何具有相同 ID 的文件。 (写入不存在的文件)
  2. 获取单个文档。
  3. 我无法更新、删除或列出任何现有文件。

这些假设是对的吗?

因为现在,我有一个奇怪的行为:

使用此规则,我可以覆盖现有文件。这是一个错误?

在我的客户端中,如果我上传了一个文件,然后使用相同的引用上传了一个新文件,规则就同意了。因此,覆盖第一个上传的文件。

使用 Flutter 2.0(稳定频道)和 firebase_storage 8.0.0

重现应用程序的最小代码
import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

const FILES_DIR = "filesDir";

void main() async {
  //
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  runApp(MyApp());

  await uploadFiles();
}

Future<void> uploadFiles() async {
  //
  var firstfile = File('lib/someimage.png');
  var secondFile = File('lib/otherImage.jpeg');

  Reference dirRef = FirebaseStorage.instance.ref(FILES_DIR);

  var firstTask = await dirRef.putFile(firstfile);
  assert(firstTask.state == TaskState.success);

  var secondTask = await dirRef.putFile(secondFile);
  assert(secondTask.state == TaskState.success);
}

class MyApp extends StatelessWidget {
  //
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Container(
        child: const Center(child: Text("Minimum Flutter aplication for test purposes")),
      ),
    );
  }
}

update 权限仅适用于元数据更新。它在参考文档 here:

中有所暗示

The write method covers all requests where file data or metadata is written, including file uploads, file deletes, and file metadata updates.

但这绝对应该更明确,所以我提交了一个错误来更新它。


您已经可以实施您的用例,但您将通过 create 规则来实现:

allow create: if resource == null

让我知道这是否有效。