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
相关产品推荐
相关产品推荐

