繁体   English   中英

如何等待firebase存储上传图片后再使用?

[英]How to wait for firebase storage to upload image before using it?

我正在尝试创建帖子,但我必须等待图像上传到 firebase 存储,然后才能真正创建帖子。 这只是创建一个带有空 imageURL 的帖子:

private func createFeedPost(feedPost: FeedPost) {
        Task {
            await persistImageToStorage()
        }
         FirebaseManager.shared.firestore.collection("feedposts").document(feedPost.id)
.setData(["commentsCount": feedPost.commentsCount, "description": feedPost.description, 
"feedImageUrl": feedPost.feedImageUrl, "id": feedPost.id, "likesCount": feedPost.likesCount, 
"locked": feedPost.locked, 
"price": feedPost.price, "timestamp": feedPost.timestamp])
    }
private func persistImageToStorage() async {
        let ref = FirebaseManager.shared.storage.reference(withPath: imageId)
        guard let imageData = self.image?.jpegData(compressionQuality: 0.5)
            else { return }
        ref.putData(imageData, metadata: nil) { metadata, err in
            if let err = err {
                print(err)
                return
            }
            ref.downloadURL { url, err in
                if let err = err {
                        print(err)
                        return
                }
                
                guard let url = url else { return }
                self.imageUrl = url.absoluteString // here is where I set the imageURL
            }
        }
    }

上传图像后,有没有办法从 firebase 存储中取回一些东西?

编辑:

我尝试使用完成,但这也没有设置 imageURL

 private func persistImageToStorage(complete:()->()) {
        let ref = FirebaseManager.shared.storage.reference(withPath: imageId)
        guard let imageData = self.image?.jpegData(compressionQuality: 0.5)
            else { return }
        ref.putData(imageData, metadata: nil) { metadata, err in
            if let err = err {
                print(err)
                return
            }
            ref.downloadURL { url, err in
                if let err = err {
                        print(err)
                        return
                }
                
                guard let url = url else { return }
                self.imageUrl = url.absoluteString
            }
        }
        complete()
    }

    private func createFeedPost(feedPost: FeedPost) {
        persistImageToStorage(complete: { () -> () in
            FirebaseManager.shared.firestore.collection("feedposts").document(feedPost.id).setData(["commentsCount": feedPost.commentsCount, "description": feedPost.description, "feedImageUrl": feedPost.feedImageUrl, "id": feedPost.id, "likesCount": feedPost.likesCount, "locked": feedPost.locked, "price": feedPost.price, "timestamp": feedPost.timestamp])
        })
    }

对于任何time-consumptionlong-waiting ,我建议使用您所考虑的异步逻辑。

这是使您的类型定义更有意义的类型typealias

/// (File URL, Error Message/Code
typealias FireBaseUploadResponseHandler = (String?, String?) -> Void

所以你的代码将是:

private func persistImageToStorage(image: UIImage?, done: @escaping FireBaseUploadResponse) {

    guard let imageData = image?.jpegData(compressionQuality: 0.5) 
    else { return done(nil, "IMG_TO_DATA_FAILED") }

    let ref = FirebaseManager.shared.storage.reference(withPath: imageId)
    ref.putData(imageData, metadata: nil) { metadata, err in
        if let err = err {
            print(err)
            return done(nil, err.localizedDescription)
        }

        ref.downloadURL { url, err in                
            guard let url = url else { return done(nil, err.localizedDescription) }
            done(url.absoluteString, nil) // Pass your downloaded URL here to closure `done`
        }
    }
}

用法:

private func createFeedPost(feedPost: FeedPost, done: escaping (Bool) -> Void) {
    self.persistImageToStorage(image: self.image) { url, error in
        guard let _url = url else { return done(false) }
        // now _url is available to use, it is public url of your uploaded image
        FirebaseManager.shared.firestore.collection("feedposts")
            .document(feedPost.id)
            .setData(["commentsCount": feedPost.commentsCount, "description": feedPost.description, 
"feedImageUrl": feedPost.feedImageUrl, "id": feedPost.id, "likesCount": feedPost.likesCount, 
"locked": feedPost.locked, 
"price": feedPost.price, "timestamp": feedPost.timestamp])

        done(true) 
    }
}

然后


createFeedPost(feedPost: [your post here]) { [weak self] success in
    guard let _self = self else { return }
    if success {
        _self.[your function to notify user that post is created]()
    } else {
        _self.[your function to notify user that it failed to create the post]()
    }
}

对于这一堆代码:

["commentsCount": feedPost.commentsCount, "description": feedPost.description, 
"feedImageUrl": feedPost.feedImageUrl, "id": feedPost.id, "likesCount": feedPost.likesCount, 
"locked": feedPost.locked, 
"price": feedPost.price, "timestamp": feedPost.timestamp]

我建议您使用任何JSON 编码器/解码器/解析器,例如ObjectMapperCodable (内置)。 简化您的逻辑并易于维护。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM