【问题标题】:update firebase database from current user从当前用户更新 firebase 数据库
【发布时间】:2019-06-21 04:27:25
【问题描述】:

我想将图像存储在 firebase 存储中并创建 url,而不是从我当前在 firebase 的数据库中更新值,但它没有从当前用户存储在 firebase 数据库中。这是我的代码,我哪里做错了?

fileprivate func saveToFirebase(image: UIImage) {
    guard let imageData = image.jpegData(compressionQuality: 0.3) else { return }
    let uuidName = UUID().uuidString

    Storage.storage().reference().child("profile_images").child(uuidName).putData(imageData, metadata: nil) { (metadata, error) in
        if let err = error {
            print("???? -- Failed to upload images -- ????")
            print("???? -- \(err) -- ????")
            return
        }

        metadata?.storageReference?.downloadURL(completion: { (url, error) in
            if let err = error {
                print("???? -- Failed to create URL -- ????")
                print("???? -- \(err) -- ????")
                return
            }

            guard let profileImageURL = url?.absoluteString else { return }
            guard let currentUID = Auth.auth().currentUser?.uid else { return }
            let userProfileURL = ["profileImageURL": profileImageURL]

            Database.database().reference().child("users").child(currentUID).updateChildValues(userProfileURL, withCompletionBlock: { (error, reference) in
            if let err = error {
                    print("???? -- Failed to create URL -- ????")
                    print("???? -- \(err) -- ????")
                    return
                }
                print("✅ -- Successfully update user data -- ✅")
            })
        })
    }
}

【问题讨论】:

  • 您有几种可能导致静默失败的情况,例如您的保护语句返回 void,以及用于下载元数据 URL 的可选链接调用。将一些 cmets 添加到代码的这些部分,以便您可以准确区分导致问题的原因。
  • @Callam 所以我需要使用 if let 而不是 guard let?
  • 当你尝试metadata?.storageReference?.downloadURL

标签: swift firebase firebase-realtime-database firebase-storage


【解决方案1】:

首先,我们可以创建一个枚举来表示可能发生的不同故障。一些我们认为是错误的场景(比如一个守卫返回 void,或者一个断开的链式可选)会默默地失败。这里我们可以封装需要处理的不同故障场景。

enum ProfileImageUploadError: Error {
    case unauthenticatedUser
    case invalidImageData
    case failedDataUpload(Error?)
    case failedDownloadURL(Error?)
    case failedProfileUpdate(Error?)

    var localizedDescription: String {
        switch self {
        case .failedDataUpload: return "Failed to upload data"
        case .failedDownloadURL: return "Failed to download URL"
        case .failedProfileUpdate: return "Failed to update profile"
        default: return "\(self)"
        }
    }

    var underlyingError: Error? {
        switch self {
        case .failedDataUpload(let err): return err
        case .failedDownloadURL(let err): return err
        case .failedProfileUpdate(let err): return err
        default: return nil
        }
    }
}

接下来,我们可以立即确定我们有一个经过身份验证的用户并且图像数据已检出。当守卫失败时,我们调用完成块传递该场景的错误案例。为了保持这一点,我们构建了对存储和数据库提供程序的引用,并尝试序列捕获错误。

鉴于最初上传数据没有错误,我们可以假设图像已上传。除了使用可选的元数据,我们还可以使用我们之前构建的存储引用来下载 URL。

随着我们继续执行一系列操作,我们正在尝试充分处理我们认为的错误,直到成功完成,此时我们可以将保存的 URL 返回到 Firebase 数据库。

func uploadProfileImage(_ image: UIImage, completion: @escaping (URL?, ProfileImageUploadError?) -> ()) {

    guard let currentUser = Auth.auth().currentUser else {
        return completion(nil, .unauthenticatedUser)
    }

    guard let imageData = image.jpegData(compressionQuality: 0.3) else {
        return completion(nil, .invalidImageData)
    }

    let storagePath = "profile_images/\(UUID().uuidString)"
    let databasePath = "users/\(currentUser.uid)/profileImageURL"

    let profileImageDataRef = Storage.storage().reference(withPath: storagePath)
    let profileImageURLRef = Database.database().reference(withPath: databasePath)

    profileImageDataRef.putData(imageData, metadata: nil) { (metadata, error) in
        guard error == nil else {
            return completion(nil, .failedDataUpload(error))
        }

        profileImageDataRef.downloadURL { (url, error) in
            guard let profileImageURL = url?.absoluteString else {
                return completion(nil, .failedDownloadURL(error))
            }

            profileImageURLRef.setValue(profileImageURL, withCompletionBlock: { (error, ref) in
                guard error == nil else {
                    return completion(nil, .failedProfileUpdate(error))
                }

                completion(url, nil)
            })
        }
    }
}

最后,这是您在现有函数中使用该函数的方式。

fileprivate func saveToFirebase(image: UIImage) {
    uploadProfileImage(image) { (url, error) in
        if let error = error {
            print("? -- \(error.localizedDescription) -- ?")
            print("? -- \(error.underlyingError.debugDescription) -- ?")
        } else {
            print("✅ -- Successfully update user data -- ✅")
            print("✅ -- \(url.debugDescription) -- ✅")
        }
    }
}

这未经测试

所以回顾一下,你的函数中的某些行可能会默默地“失败”,这可以通过充分处理“可选”和完成错误或简单地打印语句来解决。我认为是导致问题的 URL 下载的可选属性链 - 特别是 metadata?.storageReference?.downloadURL 中的元数据属性。

【讨论】:

  • 嘿@Callam 谢谢你它工作得很好,我从来没有像你那样使用枚举来处理错误。向你学习很多:)
【解决方案2】:

试试这个.. useruid 是 firbase uid

    let storageRef = Storage.storage().reference().child("profile_images").child(useruid)
                storageRef.putData(imagedata, metadata: nil, completion: { (metadatas, error) in
                    if error != nil {                                              
                     print("Couldn't Upload Image")
                                    } else {
                                        print("Uploaded")
                                      print(metadatas!)
                                        storageRef.downloadURL(completion: { (url, error) in
                                            if error != nil {
                                                print(error!)
                                                return

                                            }
                                            if url != nil {

                          let imageurl = String(describing: url!)
                         print(imageurl)                                            }
                                        })
                            }
                })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多