Данные загружаются в Firebase Storage, но не обновляют значение дочернего узла - PullRequest
0 голосов
/ 23 сентября 2019

Моя проблема в том, что я загружаю изображение в хранилище Firebase, но URL-адрес не обновляется до дочернего узла в моей базе данных, поэтому я не могу ссылаться на изображение.

Я проверил, чтобы убедиться, чтоЯ правильно ввожу значения своей базы данных, и обновление дочерних узлов, кажется, работает за пределами этой конкретной функции.Я попытался добавить очередь отправки, так как это асинхронная функция, но я не добился успеха.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        var selectedImageFromPicker: UIImage?
        if let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            selectedImageFromPicker = originalImage
            print("The photo is \(originalImage)")
        }
        if let selectedImage = selectedImageFromPicker, let cell = selectedCell {
            cell.imageContainer.image = selectedImage
            print("My image is now \(String(describing: cell.imageContainer.image))")
            guard let user = Auth.auth().currentUser else {return}
            let uid = user.uid
            let imageName = NSUUID().uuidString
            let storageRef = Storage.storage().reference().child("\(imageName).png")
            if let uploadData = cell.imageContainer.image!.pngData() {
            storageRef.putData(uploadData, metadata: nil, completion:
                { (metadata, error) in
                    if error != nil {
                        print(error as Any)
                        return
                    }
// Function doesn't seem to behave properly after this line
                    storageRef.downloadURL(completion: { (url, error) in
                        if let error = error {
                            print(error.localizedDescription)
                            return
                        } else {
                            let downloadUrl = url?.absoluteString
                            var valueKey = ""
                            if cell.activeCell == "0" { valueKey = "imageOne" } else if cell.activeCell == "1" {
                                valueKey = "imageTwo"} else if cell.activeCell == "2" { valueKey = "imageThree"} else if cell.activeCell == "3" { valueKey = "imageFour" } else if cell.activeCell == "4" { valueKey = "imageFive" } else if cell.activeCell == "5" { valueKey = "imageSix"} else { valueKey = "imageSeven" }

                            print("the node is titled \(valueKey)")
                            self.value = [valueKey: downloadUrl] as [String : AnyObject]
                            print("Here it is \(self.value) for \(uid)")
                        }
                    })

                    self.updateImageData(uid: uid, values: self.value)
                    print(metadata as Any)
                })
            }
            collectionView.reloadData()
        }
        dismissView()
    }

func updateImageData(uid: String, values: [String: AnyObject]) {
        Database.database().reference().child("profile_images").child(uid).updateChildValues(values as [AnyHashable : Any], withCompletionBlock: { (error, ref) in
            if let error  = error {
                print("Failed to update database values with error", error.localizedDescription)
                return
            }
        })
    }

ожидаемые результаты - увидеть ссылку URL в качестве значения для соответствующего ключа внутри базы данных..

1 Ответ

0 голосов
/ 23 сентября 2019

Метод storageRef.downloadURL вызывает сервер и может занять некоторое время.Вместо того, чтобы блокировать код и сделать приложение невосприимчивым к вашим пользователям, ваш основной код продолжает работу и немедленно вызывает self.updateImageData(uid: uid, values: self.value) без правильного URL.Затем, когда сервер вернул правильный URL-адрес для загрузки, ваш обработчик завершения запускается и устанавливает self.value.

. По этой причине весь код, который требует URL-адрес загрузки, должен быть в обработчике завершения storageRef.downloadURL.

Что-то вроде:

storageRef.downloadURL(completion: { (url, error) in
    if let error = error {
        print(error.localizedDescription)
        return
    } else {
        let downloadUrl = url?.absoluteString
        var valueKey = ""
        if cell.activeCell == "0" { valueKey = "imageOne" } else if cell.activeCell == "1" {
            valueKey = "imageTwo"} else if cell.activeCell == "2" { valueKey = "imageThree"} else if cell.activeCell == "3" { valueKey = "imageFour" } else if cell.activeCell == "4" { valueKey = "imageFive" } else if cell.activeCell == "5" { valueKey = "imageSix"} else { valueKey = "imageSeven" }

        self.value = [valueKey: downloadUrl] as [String : AnyObject]

        self.updateImageData(uid: uid, values: self.value)
    }
})
...