如何完成图像到 Firebase 存储的上传,然后将 imageUrl 保存到 Firebase 数据库

How to finish the upload of images to Firebase Storage and then save the imageUrl to the Firebase Database

我没有找到令我满意的答案,希望您有任何想法。我想将我的图片上传到 Firebase 存储并将 imageUrls 保存到 Firebase 数据库中。

     var imageUrls = [String]()

     func uploadImagesToStorage(imagesArray: [UIImage]) {


    for i in imagesArray {

        guard let uploadData = UIImageJPEGRepresentation(i, 0.3) else { return }
        let fileName = NSUUID().uuidString

         FIRStorage.storage().reference().child("post_Images").child(fileName).put(uploadData, metadata: nil) { (metadata, err) in

            if let err = err {
            return
            }

            guard let profileImageUrl = metadata?.downloadURL()?.absoluteString else { return }
            self.imageUrls.append(profileImageUrl)

        }.resume()

  } //..End loop
       saveToDatabaseWithImageUrl(imageUrls: imageUrls)

使用 uploadImagesToStorage(imagesArray: [UIImage]) 方法上传图片。此方法获取一个数组作为参数,其中包含我要上传的图像。在上传图像时,我正在从 firebase 给我的元数据中下载 imageUrl 信息,并将该 imageUrl 保存到 imageUrls 数组中。必须使用 For 循环来保存每张图片的 imageUrl 信息。当图像上传并且 imageUrls 数组填充了 imageUrl 信息时,我调用函数 func saveToDatabaseWithImageUrl(imageUrls: [String]) 来保存imageUrls 到数据库中。检查 Firebase 我看到图像已保存到 Firebase 存储中,但 imageUrls 未保存到 Firebase 数据库中。在调试我的代码时,我发现这种行为的原因是在上传图像时代码跳转到下一行。因此它调用带有空 imageUrls 数组的 saveToDatabaseWithImageUrls。我阅读了 [Documentation][1] 并尝试使用 .resume() 方法管理上传。它仍然跳转到 saveToDatabaseWithImageUrl 方法。不知道怎么保证上传完成再执行下一行代码。谢谢你的帮助。

它的发生是因为您的 .child("post_Images").child(fileName).put 异步调用的成功块。其余代码同步。因此,您的 for 开始上传照片,之后您将 URL 保存到数据库,但 URL 为空,因为您没有等待完成上传。

我根据DispathGroup

给你一个完美的解决方案
//Create DispatchGroup
let fetchGroup = DispatchGroup()

for i in imagesArray {
    guard let uploadData = UIImageJPEGRepresentation(i, 0.3) else { return }

    let fileName = NSUUID().uuidString
    //Before every iteration enter to group
    fetchGroup.enter()        
    FIRStorage.storage().reference().child("post_Images").child(fileName).put(uploadData, metadata: nil) { (metadata, err) in
        if let err = err {
        fetchGroup.leave()
        return
        }

        guard let profileImageUrl = metadata?.downloadURL()?.absoluteString else { return }
        self.imageUrls.append(profileImageUrl)
        //after every completion asynchronously task leave the group
        fetchGroup.leave()
    }.resume()
}

并且了解 id 魔法

fetchGroup.notify(queue: DispatchQueue.main) {
    //this code will call when number of enter of group will be equal to number of leaves from group
    //save your url here
    saveToDatabaseWithImageUrl(imageUrls: imageUrls)
}

这个解决方案不阻塞线程,这里的一切都是异步工作的。