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;
}
}
}
根据官方文档,使用这个规则我可以:
- 上传新文件,如果没有任何具有相同 ID 的文件。 (写入不存在的文件)
- 获取单个文档。
- 我无法更新、删除或列出任何现有文件。
这些假设是对的吗?
因为现在,我有一个奇怪的行为:
使用此规则,我可以覆盖现有文件。这是一个错误?
在我的客户端中,如果我上传了一个文件,然后使用相同的引用上传了一个新文件,规则就同意了。因此,覆盖第一个上传的文件。
使用 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
让我知道这是否有效。
基于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;
}
}
}
根据官方文档,使用这个规则我可以:
- 上传新文件,如果没有任何具有相同 ID 的文件。 (写入不存在的文件)
- 获取单个文档。
- 我无法更新、删除或列出任何现有文件。
这些假设是对的吗?
因为现在,我有一个奇怪的行为:
使用此规则,我可以覆盖现有文件。这是一个错误?
在我的客户端中,如果我上传了一个文件,然后使用相同的引用上传了一个新文件,规则就同意了。因此,覆盖第一个上传的文件。
使用 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
让我知道这是否有效。