Unity使用Firebase Storage上传图片遇StorageException权限拒绝求助
解决Firebase Storage上传时的Permission Denied异常
从你给出的错误日志来看,核心问题是Firebase.Storage.StorageException: Permission denied,这是Firebase Storage最常见的问题之一,下面我帮你梳理几个最可能的原因和对应的解决办法:
1. Firebase Storage安全规则限制
默认情况下,Firebase Storage的安全规则是只允许已认证的用户读写,甚至有些新创建的项目规则可能更严格(比如完全禁止访问)。你可以按以下步骤检查和修改:
- 打开Firebase控制台,进入你的项目的「Storage」模块
- 切换到「规则」标签页,查看当前规则。默认规则大概是这样:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } } - 如果你的测试场景不需要用户登录,可以临时修改为宽松规则用于测试(注意生产环境一定要改回严格规则,避免数据泄露):
修改后点击「发布」,然后重新测试上传。rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if true; } } }
2. 未完成用户认证(如果规则要求认证)
如果你的安全规则要求request.auth != null,但你的代码里没有实现Firebase Auth的登录流程,就会触发权限拒绝。解决办法:
- 在你的Unity项目中初始化Firebase Auth,添加匿名登录或者邮箱密码登录的逻辑。比如匿名登录的代码示例:
确保在调用Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance; auth.SignInAnonymouslyAsync().ContinueWith(task => { if (task.IsCanceled) { Debug.LogError("SignInAnonymously was canceled."); return; } if (task.IsFaulted) { Debug.LogError("SignInAnonymously encountered an error: " + task.Exception); return; } Firebase.Auth.FirebaseUser newUser = task.Result; Debug.LogFormat("User signed in successfully: {0} ({1})", newUser.DisplayName, newUser.UserId); });PutFileAsync之前,用户已经完成登录。
3. 存储引用URL或路径错误
检查你的存储引用URL是否正确:
- 你代码里的
storage.GetReferenceFromUrl("gs://<myurl>.appspot.com/"),要确认<myurl>是你Firebase项目的实际存储桶名称,你可以在Firebase控制台的Storage页面顶部找到这个地址。 - 另外,确认
art_image_ref = storage_ref.Child("images/innocence.jpg")中的路径images/innocence.jpg没有违反规则里的路径匹配(比如规则里有没有限制特定路径的访问)。
4. 本地文件读取权限问题
在Unity中,如果传入的path对应的文件没有读取权限,也可能间接导致Firebase Storage的权限错误(不过这种情况更少见):
- 确保你传入的文件路径是正确的,比如在Windows上是绝对路径,在移动端是应用可访问的沙箱路径。
- 可以先通过
File.Exists(path)检查文件是否存在,再执行上传操作。
附上你提供的代码和错误信息,方便其他开发者参考:
你的上传代码
public void firetalk(string path) { Firebase.Storage.FirebaseStorage storage = Firebase.Storage.FirebaseStorage.DefaultInstance; Firebase.Storage.StorageReference storage_ref = storage.GetReferenceFromUrl("gs://<myurl>.appspot.com/"); Firebase.Storage.StorageReference art_image_ref = storage_ref.Child("images/innocence.jpg"); art_image_ref.PutFileAsync(path).ContinueWith((Task<StorageMetadata> task) => { if (task.IsFaulted || task.IsCanceled) { Debug.Log(task.Exception.ToString()); // Uh-oh, an error occurred! } else { // Metadata contains file metadata such as size, content-type, and download URL. Firebase.Storage.StorageMetadata metadata = task.Result; string download_url = metadata.DownloadUrl.ToString(); Debug.Log("Finished uploading..."); Debug.Log("download url = " + download_url); } }); }
错误日志
System.AggregateException: Exception of type 'System.AggregateException' was thrown. ----------------- Firebase.Storage.StorageException: Permission denied. Could not perform this operation UnityEngine.Debug:Log(Object) GracesGames.SimpleFileBrowser.Scripts.explorer_script:m__0(Task`1) (at Assets/scripts/explorer_script.cs:85) System.Threading.Tasks.TaskCompletionSource`1:SetException(Exception) Firebase.Storage.StorageReference:CompleteTask(Task`1, TaskCompletionSource`1, Func`1, String, Boolean) Firebase.Storage.c__AnonStorey6:<>&m__0(Task`1) System.Threading.Tasks.TaskCompletionSource`1:SetException(Exception) Firebase.Storage.c__AnonStorey0:<>&m__0() Firebase.Storage.Future_StorageMetadata:SWIG_CompletionDispatcher(Int32) Firebase.AppUtilPINVOKE:PollCallbacks() Firebase.AppUtil:PollCallbacks() Firebase.Platform.FirebaseAppUtils:PollCallbacks() Firebase.Platform.FirebaseHandler:Update() Firebase.Platform.FirebaseMonoBehaviour:Update()
内容的提问来源于stack exchange,提问作者VivekChoudhary1
相关产品推荐
相关产品推荐

