我正在尝试编写与 Firebase 交互的 Dart 代码,以便该代码上传用户上传到 Cloud Storage 的照片的 zip 文件。这是我的代码:
final tempDir = await getTemporaryDirectory();
final zipPath = '${tempDir.path}/trainingData.zip';
final zipFile = await File(zipPath).writeAsBytes(encodedArchive);
final storage = FirebaseStorage.instance;
final storageRef = FirebaseStorage.instance.ref();
final picRef = storageRef.child("pics.zip");
final picCollectionsRef =
storageRef.child("picCollections/pics.zip");
assert(picRef.name == picCollectionsRef.name);
assert(picRef.fullPath != picCollectionsRef.fullPath);
try {
await picRef.putFile(
zipFile,
SettableMetadata(
contentType: "application/zip",
));
} catch (e) {
print('Error: Zip File not uploaded correctly - $e');
}
var downloadURL = await trainingDataRef.getDownloadURL();
return downloadURL;
在 iPhone 上测试该应用程序时,我不断收到以下错误消息:
flutter: Error: Zip File not uploaded correctly - [firebase_storage/unauthorized] User is not authorized to perform the desired action.
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_storage/unauthorized] User is not authorized to perform the desired action.
#0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:651:7)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:334:18)
<asynchronous suspension>
#2 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:534:43)
<asynchronous suspension>
#3 MethodChannelReference.getDownloadURL (package:firebase_storage_platform_interface/src/method_channel/method_channel_reference.dart:45:36)
<asynchronous suspension>
这是我的存储安全规则:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth.uid == userId;
}
match /users/{userId}/{allPaths=**} {
allow read: if true;
allow write: if request.auth.uid == userId;
}
}
}
出于安全原因,我不想更改规则以允许未经身份验证的任何人进行读写。当我测试时,用户已完全登录 Firebase,并且他们的帐户存在于 Firebase 中。
为什么用户无权上传 zip 文件?
您的安全规则允许用户写入以
/users/<their user ID>
开头的路径。
但是您的代码不遵循这些规则,并尝试写入
/pics.zip
。由于这不符合您自己的规则,因此写入会被拒绝。
要解决此问题,请将您的
picRef
设置为:
if (FirebaseAuth.instance.currentUser != null) {
final uid = FirebaseAuth.instance.currentUser!.uid;
final picRef = storageRef.child("/users/$uid/pics.zip");
...
}