ios - 从firebase存储返回的url是nil Swift4
问题描述
我正在尝试将图像上传到 firebase 存储并获取下载 url 以将其保存在数据库中,但我得到一个 nil 值并且该函数在检查时返回。我遵循了其他帖子的文档和解决方案,但我看不出我在哪里弄错了。功能是:
func uploadImage(completed: @escaping (Bool) -> (),_ image: UIImage ){
print(" ############## UPLOAD STARTED ###########")
// let stringURL: String?
// guard let uid = Auth.auth().currentUser?.uid else {return} // use the userUid to sign the alert
// Create a root reference
let storageRef = Storage.storage().reference()
// Create a reference to "mountains.jpg"
// let alertsRef = storageRef.child("userAlertImages.jpg")//("user/\(uid)") // change path for userAlertImages path
// Create a reference to 'images/mountains.jpg'
let alertsImagesRef = storageRef.child("Alert Images/userAlertImages.jpg")
// While the file names are the same, the references point to different files
// alertsRef.name == alertsImagesRef.name; // true
// alertsRef.fullPath == alertsImagesRef.fullPath; // false
let imageData = UIImageJPEGRepresentation(image, 0.5)
let metaData = StorageMetadata()
metaData.contentType = " jpeg " // data type
metaData.customMetadata = ["k1": "",
"k2" : " ",
"k3" : "",
"k4" : ""]
alertsImagesRef.putData(imageData! as Data , metadata: metaData) { metaData, error in
if(error != nil){
print(error as Any)
return
}
}
// Fetch the download URL
alertsImagesRef.downloadURL { (url,error) in
guard let downloadURL = url else {
print("@@@@@@@@@@ downloaded url is: \(url) @@@@@@@@@@@@@")
return
}
NewMapViewController.alertImageURL = (url?.absoluteString) ?? ""
// NewMapViewController.alertImageURL = (downloadURL)
print("######### url is:\(String(describing: url)) #########")
completed(true)
// self.postAlertNotification()
self.tapCounter = 0
self.performSegue(withIdentifier: "chooseIconSegue", sender: self)
}
}
你能看到错误在哪里吗?非常感谢。
解决方案
想一想,我意识到downloadURL
fetch 实际上是在图像上传完成之前完成的,那是因为 Firebase 是异步的。所以我completion block
在上传部分添加了一个,并在其中completion scope
放入了downloadURL
获取部分。它不是快速眨眼,我会感谢任何关于加快速度的建议,因为这样在segue
执行之前会有一点延迟。这一点都不烦人,我可以而且可能应该添加一个小转轮来向用户显示应用程序没有冻结,但如果可能的话,我宁愿完全避免滞后。我离开了prints
写这篇文章是为了希望这篇文章能帮助像我一样刚接触 Firebase 的其他人,提供详细的几乎一步一步的指导,因为这种答案确实对我有帮助,但我还没有找到任何关于这个主题的答案。改写函数为:
func uploadImage(completed: @escaping (Bool) -> (),_ image: UIImage ){
print(" ############## UPLOAD STARTED ###########")
// Create a root reference
let storageRef = Storage.storage().reference()
// Create a reference to Images folder
let alertsImagesRef = storageRef.child("Alert Images")
// Create a reference for new images
let uuid = UUID()
let imageRef = alertsImagesRef.child("userAlertImage \(uuid).jpg")
let imageData = UIImageJPEGRepresentation(image, 0.5)
let metaData = StorageMetadata()
metaData.contentType = " jpeg " // data type
metaData.customMetadata = ["k1": "",
"k2" : " ",
"k3" : "",
"k4" : ""]
imageRef.putData(imageData! as Data , metadata: metaData, completion: { metaData, error in
if(error != nil){
print(error as Any)
return
}
print(" ####### image uploaded #######")
self.tapCounter = 0
self.performSegue(withIdentifier: "chooseIconSegue", sender: self)
// fetch url v2
imageRef.downloadURL(completion: { (url, err) in
if let err = err {
print("Error downloading image file, \(err.localizedDescription)")
return
}
guard let url = url else { return }
//Now you have the download URL for the image, and can do whatever you want with it.
NewMapViewController.alertImageURL = url.absoluteString
print(" ######### url is:\(String(describing: url)) #########")
completed(true)
// self.postAlertNotification()
// self.tapCounter = 0
// self.performSegue(withIdentifier: "chooseIconSegue", sender: self)
print(" ############## UPLOAD ENDED ###########")
})
})
}
推荐阅读
- r - 聚合个体密度的直方图
- vb.net - VB.NET & SQL,在调用 Read() 之前访问字段的尝试无效
- python - 如果 x>=1,则为 1,否则为 0,作为纯数学方程?
- python - 带有 ConnectionPaths 对象布局问题的 Matplotlib 绘图
- flutter - 防止更改基于设备屏幕大小的文本大小 Flutter
- angular - 为什么对象类型正在改变“订阅”?
- python - 在两张特定卡上加载 MirroredStrategy 会导致 CUDA_ERROR_ILLEGAL_ADDRESS,但它们适用于其他卡
- ruby-on-rails - 如何在不使用 eval 的情况下动态调用方法?
- javascript - 如何在对象数组中添加元素?
- c# - 如何在我的 C# 代码中使用 MSBuild 参数?