Unity SDK中Firebase PutFileAsync能否恢复上传?如何获取previousSessionUri?
Firebase Unity SDK 断点续传问题解答
用户问题
- 能否通过Unity SDK的PutFileAsync恢复文件上传?
- Firebase是否支持Unity SDK的文件上传恢复功能?
用户补充:根据官方文档,PutFileAsync方法可传入previousSessionUri参数实现上传恢复,但不清楚如何获取该Uri。参考其他平台文档,可通过UploadState获取该Uri,但自己编写的代码中state.UploadSessionUri始终返回null,疑惑是代码存在问题,还是Firebase SDK尚未实现该功能。
用户代码如下:
bool isSessionRetrieved = false; Uri sessionUri = null; var progressState = new StorageProgress<UploadState>(state => { sessionUri = state.UploadSessionUri; if (!isSessionRetrieved && sessionUri != null) { isSessionRetrieved = true; Debug.Log($"upload session: {sessionUri.AbsolutePath}"); } // called periodically during the upload Debug.Log(String.Format("Progress: {0} of {1} bytes transferred.", state.BytesTransferred, state.TotalByteCount)); }); uploadTask = fileRef.PutFileAsync(path, null, progressState, cToken, null) .ContinueWith((Task<StorageMetadata> task) => { if (task.IsFaulted || task.IsCanceled) { Debug.LogError(task.Exception); } else { StorageMetadata metadata = task.Result; string md5Hash = metadata.Md5Hash; Debug.Log("Finished uploading..."); Debug.Log("md5 hash = " + md5Hash); PlayerPrefs.DeleteKey("prevSession"); } });
解答
核心结论
Firebase Unity SDK支持文件上传恢复(断点续传)功能,PutFileAsync确实可以通过传入previousSessionUri参数恢复中断的上传任务。
UploadState.UploadSessionUri返回null的原因及解决
触发条件限制
该会话Uri只有在上传任务被中断(如主动取消、网络断开),且SDK已经成功创建了云端上传会话后才会生成。如果上传全程顺利完成,或者还未建立云端会话就中断,都不会返回有效Uri。代码逻辑优化
你的代码逻辑本身没问题,但需要注意:应在拿到会话Uri时立刻保存(比如存入PlayerPrefs),而不是仅在进度回调中打印。另外,在任务中断的回调里也需要做兜底检查,确保会话Uri被保存。SDK版本验证
旧版本Firebase Unity SDK可能存在该字段未实现的情况,建议升级到最新稳定版。
修正后的示例代码
带会话保存的上传代码
bool isSessionRetrieved = false; Uri sessionUri = null; var progressState = new StorageProgress<UploadState>(state => { sessionUri = state.UploadSessionUri; if (!isSessionRetrieved && sessionUri != null) { isSessionRetrieved = true; Debug.Log($"上传会话Uri: {sessionUri.ToString()}"); // 保存会话Uri到本地,用于后续恢复 PlayerPrefs.SetString("prevSession", sessionUri.ToString()); PlayerPrefs.Save(); } Debug.Log($"上传进度: {state.BytesTransferred}/{state.TotalByteCount} 字节"); }); uploadTask = fileRef.PutFileAsync(path, null, progressState, cToken, null) .ContinueWith(task => { if (task.IsFaulted || task.IsCanceled) { Debug.LogError(task.Exception); // 兜底:如果进度回调中没拿到Uri,这里检查并保存 if(sessionUri != null && !isSessionRetrieved) { PlayerPrefs.SetString("prevSession", sessionUri.ToString()); PlayerPrefs.Save(); } } else { StorageMetadata metadata = task.Result; string md5Hash = metadata.Md5Hash; Debug.Log("上传完成..."); Debug.Log("MD5哈希值: " + md5Hash); PlayerPrefs.DeleteKey("prevSession"); } });
恢复上传的代码
// 检查本地是否保存了未完成的上传会话 if(PlayerPrefs.HasKey("prevSession")) { string savedSessionStr = PlayerPrefs.GetString("prevSession"); if(Uri.TryCreate(savedSessionStr, UriKind.Absolute, out Uri prevSessionUri)) { var progressState = new StorageProgress<UploadState>(state => { Debug.Log($"恢复上传进度: {state.BytesTransferred}/{state.TotalByteCount} 字节"); }); // 传入previousSessionUri参数恢复上传 uploadTask = fileRef.PutFileAsync(path, null, progressState, cToken, prevSessionUri) .ContinueWith(task => { if (task.IsFaulted || task.IsCanceled) { Debug.LogError(task.Exception); } else { Debug.Log("恢复上传完成..."); PlayerPrefs.DeleteKey("prevSession"); } }); } }
内容的提问来源于stack exchange,提问作者Konstantin Zhirnov
相关产品推荐
相关产品推荐

