You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的原因及解决

  1. 触发条件限制
    该会话Uri只有在上传任务被中断(如主动取消、网络断开),且SDK已经成功创建了云端上传会话后才会生成。如果上传全程顺利完成,或者还未建立云端会话就中断,都不会返回有效Uri。

  2. 代码逻辑优化
    你的代码逻辑本身没问题,但需要注意:应在拿到会话Uri时立刻保存(比如存入PlayerPrefs),而不是仅在进度回调中打印。另外,在任务中断的回调里也需要做兜底检查,确保会话Uri被保存。

  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:29:53