Unity中如何下载Firebase Storage整个文件夹内容?
Firebase Storage 文件夹完整下载方案(Unity Android)
由于Firebase Storage没有提供直接下载整个文件夹的API,我们需要先列出目标文件夹下的所有文件,再逐个下载。以下是适配你现有代码的完整实现:
核心实现步骤
- 获取目标文件夹的Storage引用
- 调用
ListAsync()获取文件夹内的所有文件条目 - 提前创建本地存储目录(避免下载时路径不存在)
- 遍历所有文件引用,逐个执行下载操作
- 统一处理下载成功/失败的回调
完整代码示例
using System.IO; using Firebase.Storage; using UnityEngine; using UnityEngine.Android; public class FirebaseFolderDownloader : MonoBehaviour { private FirebaseStorage storage; private StorageReference storageReference; // 替换为你的Firebase Storage根URL和目标文件夹路径 private const string STORAGE_ROOT_URL = "gs://houdini-ac884.appspot.com"; private const string TARGET_FOLDER_PATH = "uploads/your-target-folder"; // 替换成你要下载的文件夹路径 private const string LOCAL_BASE_PATH = "SparseSpatialMap"; public void StartFolderDownload() { Debug.Log("开始尝试下载文件夹..."); if (Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite)) { InitializeStorageReference(); ListAndDownloadFolderFiles(); } else { Debug.Log("无存储写入权限,请求权限中..."); easyar.GUIPopup.EnqueueMessage("权限不足,正在请求存储权限", 5); Permission.RequestUserPermission(Permission.ExternalStorageWrite); } } private void InitializeStorageReference() { storage = FirebaseStorage.DefaultInstance; storageReference = storage.GetReferenceFromUrl(STORAGE_ROOT_URL); } private void ListAndDownloadFolderFiles() { StorageReference folderRef = storageReference.Child(TARGET_FOLDER_PATH); // 列出文件夹下的所有文件(默认最多返回1000个,若文件更多需处理分页) folderRef.ListAsync().ContinueWithOnMainThread(task => { if (task.IsFaulted || task.IsCanceled) { Debug.LogError("获取文件列表失败: " + task.Exception); easyar.GUIPopup.EnqueueMessage("获取文件列表失败", 5); return; } ListResult result = task.Result; if (result.Items.Count == 0) { Debug.Log("目标文件夹为空"); easyar.GUIPopup.EnqueueMessage("文件夹为空,无需下载", 5); return; } // 创建本地目标目录 string localFolderPath = Path.Combine(Application.persistentDataPath, LOCAL_BASE_PATH, TARGET_FOLDER_PATH); if (!Directory.Exists(localFolderPath)) { Directory.CreateDirectory(localFolderPath); Debug.Log("创建本地目录: " + localFolderPath); } // 遍历所有文件并下载 int downloadedCount = 0; int totalFiles = result.Items.Count; foreach (StorageReference fileRef in result.Items) { string fileName = fileRef.Name; string localFilePath = Path.Combine(localFolderPath, fileName); fileRef.GetFileAsync(localFilePath).ContinueWithOnMainThread(downloadTask => { downloadedCount++; if (downloadTask.IsFaulted || downloadTask.IsCanceled) { Debug.LogError($"文件 {fileName} 下载失败: {downloadTask.Exception}"); easyar.GUIPopup.EnqueueMessage($"文件 {fileName} 下载失败", 3); } else { Debug.Log($"文件 {fileName} 下载完成"); } // 所有文件下载完成后提示 if (downloadedCount == totalFiles) { Debug.Log("所有文件下载完成"); easyar.GUIPopup.EnqueueMessage("文件夹下载完成", 5); } }); } }); } // 权限请求回调 private void OnApplicationFocus(bool hasFocus) { if (hasFocus && Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite)) { StartFolderDownload(); } } }
关键细节说明
- 分页处理:如果目标文件夹内文件超过1000个,需要调用
ListAsync()的重载版本,传入ListOptions通过PageToken获取下一页内容 - 本地目录创建:使用
Directory.CreateDirectory()确保下载路径存在,避免因路径不存在导致下载失败 - 异步任务管理:通过计数统计所有文件的下载状态,确保所有文件完成后给出统一提示
- 权限处理:在
OnApplicationFocus中监听权限授权结果,用户授权后自动开始下载
内容的提问来源于stack exchange,提问作者EvocativeAxis
相关产品推荐
相关产品推荐

