【问题标题】:Swift: upload multiple images to Firestore and assign URLs to objectSwift:将多个图像上传到 Firestore 并将 URL 分配给对象
【发布时间】:2020-11-06 15:44:11
【问题描述】:

我正在制作一个用户发布 2 张图片的应用。我使用 Firebase 进行存储并作为我的数据库。

在我上传图片的方法中,我想做的基本上是使用这种方法来分别返回 URL。我写了以下内容:

 private func uploadImage(image: UIImage) -> URL? {
    let randomName = UUID()
    let storageRef = storage.reference().child("\(randomName)/png")
    guard let uploadData = image.pngData() else { return nil}
    
    var imageUrl: URL?
    
    storageRef.putData(uploadData, metadata: nil) { (metadata, error) in
        if error != nil {
            print(error?.localizedDescription)
            return
        }
        storageRef.downloadURL { (url, error) in
            if error != nil {
                print(error?.localizedDescription)
            } else {
                imageUrl = url
            }
        }
    }
    return imageUrl
}

然后我编写了以下“发布”方法,该方法在点击提交按钮时运行:

  @objc func post() {
        
        if let question = questionText.text,
            let hashtagText = hashtagTextField.text,
            let userHandle = Auth.auth().currentUser?.email,
            let firstImage = left.image,
            let secondImage = right.image,
            let firstImageURL = uploadImage(image: firstImage)?.absoluteString,
            let secondImageURL = uploadImage(image: secondImage)?.absoluteString
        {
            
            db.collection("posts").addDocument(data: [
                "firstImage" : firstImageURL,
                "secondImage" : secondImageURL,
                "question" : question,
                "hashtagText" : hashtagText,
                "userHandle" : userHandle
            ]) { (error) in
                if let e = error {
                    print("There was an issue saving data to Firestore, \(e)")
                } else {
                    print("Successfully saved data")
                    
                    self.dismiss(animated: true, completion: nil)
                }
            }
        }
    }

但是,显然第一种方法不起作用,因为在返回 imageUrl 之后运行闭包,因此返回 nil。

我一直在试图弄清楚如何管理这种情况 - 我曾考虑使用循环来填充图像数组,但这变得混乱,我确信这不是处理这个问题的标准方法。任何帮助将不胜感激。

【问题讨论】:

    标签: swift database firebase google-cloud-firestore uiimage


    【解决方案1】:

    return imageUrl 放错地方了。它会在Firebase 有时间存储图像并返回 url 之前返回。

    此外,文件名也不起作用。你目前有

    storage.reference().child("\(randomName)/png")  //  xxxxx/png?
    

    应该是什么时候

    storage.reference().child("\(randomName).png")  //  xxxxx.png
    

    您不能从 Firebase 闭包“返回”数据,因为 firebase 是异步的 - 完成处理程序可能是一种解决方案,但我们不知道总用例是什么。

    假设您想将用户度假图片存储在存储中,然后将该 url 存储在 Firestore 中

     private func uploadImage(image: UIImage) {
        guard let uid = Auth.auth().currentUser?.uid else { return } //this users uid
        let storageRef = storage.reference().child(uid).child("vacation.png")
           //the path will be storage/users uid/vacation.png
        guard let uploadData = image.pngData() else { return nil}
    
        storageRef.putData(uploadData, metadata: nil) { (metadata, error) in
            if error != nil {
                print(error?.localizedDescription)
                return
            }
            storageRef.downloadURL { (url, error) in
                if error != nil {
                    print(error?.localizedDescription)
                } else {
                    if url != nil {
                       //it's here where we store the imageUrl in Firestore
                       let dict = ["theUrl": url?.absoluteURL)]
                       let userRef = self.db.collection("users").document(uid)
                           //self.db points to *my* Firestore
                       userRef.collection("my_pics").addDocument(data: dict)
                           //will store in firstore/users/uid/docId/theUrl: the url
                    }
                }
            }
        }
     }
    

    【讨论】:

    • 谢谢杰。是的,图像文件名是错字。我遇到的问题实际上是上传多个图像,然后在数据对象中设置这些图像 URL。您可以在上面看到我需要在这些对相关 url 的调用中设置 firstImage 和 secondImage ,以便以后可以从对象访问它们。但我正在努力做到这一点。上传一张图片很好,因为我可以进行 downloadURL 调用,然后从那里设置我的对象属性。但是如何从这个调用中设置两个图像 URL?
    • @DevB1 问题中没有任何内容试图将两个图像写入存储 - 这很好,因为您无论如何都不能这样做;-) 要存储两个 URL,您只需通过两次调用即可。我建议使用生成的 documentId 编写初始节点。然后调用一个函数将每个图像存储在 storage 中并将 URL 写入该 documentId,然后再次调用它以将 secondImage 写入同一个 documentId。类似于 func uploadImage(withDocId: String, fieldName: String, theImage: UIImage)。传递 docId、存储它的字段(firstImage、secondImage 等)和图像。
    猜你喜欢
    • 2018-09-08
    • 1970-01-01
    • 2019-12-29
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 2021-02-06
    相关资源
    最近更新 更多