Unity-Android无需FileContentProvider传Zip至Firebase Storage遇错求助
解决Unity安卓上传私有目录文件到Firebase Storage的简便方案
核心思路
绕开Uri访问私有文件的限制,直接读取文件的字节流或FileStream传给Firebase Storage上传接口,无需配置FileProvider或修改AndroidManifest.xml。
具体实现代码
1. 字节数组上传(适合小文件)
using Firebase.Storage; using System.IO; using System.Threading.Tasks; using UnityEngine; public class FirebaseUploadHandler : MonoBehaviour { private async Task UploadPrivateFile() { // 获取应用私有缓存目录的目标文件路径 string targetPath = Path.Combine(Application.temporaryCachePath, "myFile.zip"); if (!File.Exists(targetPath)) { Debug.LogError("目标文件不存在:" + targetPath); return; } // 读取文件为字节数组 byte[] fileData = File.ReadAllBytes(targetPath); // 初始化Firebase Storage引用 StorageReference storageRoot = FirebaseStorage.DefaultInstance.GetReferenceFromUrl("gs://你的存储桶地址"); StorageReference targetRef = storageRoot.Child("uploaded_files/myFile.zip"); // 启动上传任务 var uploadTask = targetRef.PutBytesAsync(fileData); // 监听上传进度(可选) uploadTask.Progress.ProgressChanged += (snapshot) => { float progressRate = (float)snapshot.BytesTransferred / snapshot.TotalByteCount; Debug.Log($"上传进度:{progressRate * 100:F2}%"); }; // 等待上传完成并处理结果 try { await uploadTask; Debug.Log("文件上传成功"); // 可选:获取文件下载链接 string downloadUrl = await targetRef.GetDownloadUrlAsync(); Debug.Log("文件下载链接:" + downloadUrl); } catch (System.Exception ex) { Debug.LogError("上传失败:" + ex.Message); } } // 绑定UI按钮触发上传 public void TriggerUpload() { _ = UploadPrivateFile(); } }
2. FileStream上传(适合大文件,低内存占用)
如果文件体积较大,用字节数组会占用过多内存,推荐使用文件流上传:
private async Task UploadFileStream() { string targetPath = Path.Combine(Application.temporaryCachePath, "myFile.zip"); if (!File.Exists(targetPath)) { Debug.LogError("目标文件不存在:" + targetPath); return; } StorageReference storageRoot = FirebaseStorage.DefaultInstance.GetReferenceFromUrl("gs://你的存储桶地址"); StorageReference targetRef = storageRoot.Child("uploaded_files/myFile.zip"); // 打开文件流并上传 using (FileStream fileStream = new FileStream(targetPath, FileMode.Open, FileAccess.Read)) { var uploadTask = targetRef.PutStreamAsync(fileStream); uploadTask.Progress.ProgressChanged += (snapshot) => { float progressRate = (float)snapshot.BytesTransferred / snapshot.TotalByteCount; Debug.Log($"上传进度:{progressRate * 100:F2}%"); }; try { await uploadTask; Debug.Log("文件上传成功"); } catch (System.Exception ex) { Debug.LogError("上传失败:" + ex.Message); } } }
关键细节说明
- 使用
Application.temporaryCachePath直接定位安卓应用的私有缓存目录,无需手动拼接路径,避免路径格式错误 - 该方案完全在Unity代码层实现,无需修改安卓原生配置,适配安卓10及以上的存储权限规则
- 确保已正确导入Firebase Storage Unity SDK,且
google-services.json已放置在Assets/Plugins/Android目录下
内容的提问来源于stack exchange,提问作者mcExchange
相关产品推荐
相关产品推荐

