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

Firebase Storage上传完成回调不触发及下载URL获取失败问题

我之前也碰到过一模一样的问题!文件明明已经出现在Firebase Storage里了,但所有完成回调死活不触发,progress倒是正常跑,当时折腾了好久才找到根源,给你几个排查方向:

1. 最可能的原因:uploadTask被提前释放了

Swift的ARC会自动回收没有强引用的对象,如果你的uploadTask是在某个函数里定义的局部变量,函数执行完之后这个对象就被销毁了,后续的回调自然没法触发。

解决办法是把uploadTask改成类的属性,保持强引用:

// 在你的ViewController/自定义类的顶部声明
var uploadTask: StorageUploadTask?

// 然后在上传逻辑里赋值
func uploadImage() {
    let storage = Storage.storage()
    let storageRef = storage.reference()
    guard let data = curImg?.pngData() else {
        print("Failed to convert image to data")
        return
    }
    let riversRef = storageRef.child("userUploads/Search/\(id).png")
    
    // 赋值给类属性,保持强引用
    uploadTask = riversRef.putData(data, metadata: nil) { [weak self] (metadata, error) in
        guard let self = self else { return }
        if let error = error {
            print("Upload failed: \(error.localizedDescription)")
            return
        }
        print("FIN")
        print("DONE", metadata ?? "No metadata")
        
        // 现在尝试获取下载URL
        riversRef.downloadURL { (url, error) in
            if let url = url {
                print("Download URL obtained: \(url.absoluteString)")
                // 这里处理你的URL逻辑
            } else {
                print("Failed to get download URL: \(error?.localizedDescription ?? "Unknown error")")
            }
        }
    }
}

2. 检查Firebase Storage安全规则

虽然文件能成功上传,但如果你的规则限制了读权限,调用downloadURL的时候可能因为权限问题卡住(甚至连回调都不触发)。可以先临时设置宽松规则测试:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true; // 测试用,上线前记得改回安全规则
    }
  }
}

测试完如果回调正常了,再把规则改回符合你业务需求的版本(比如只允许认证用户读写)。

3. 确认Firebase SDK版本

虽然你说更新过Pods,但可以再确认一下是不是最新版。打开Podfile,确保Firebase/Storage没有指定旧版本,然后执行:

pod update Firebase/Storage

4. 手动指定回调队列

Firebase默认会在主线程触发回调,但如果你的代码是在后台队列执行的,可能会有线程问题。可以手动指定主线程队列:

uploadTask = riversRef.putData(data, metadata: nil, queue: DispatchQueue.main) { (metadata, error) in
    // 回调会在主线程执行
    print("FIN")
    // 后续逻辑...
}

我当时就是因为把uploadTask写成了局部变量,导致回调直接消失,改成类属性之后立刻就正常了,你先试试这个方案!

内容的提问来源于stack exchange,提问作者Anters Bear

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:09:20