0
votes

I am currently trying to upload a photo URL and post caption onto my firebase database. The photos are currently being saved on firebase storage which is fine, however I would like for it to also appear on the firebase database. I repeatedly find myself dealing with this error "Value of type 'StorageMetadata' has no member 'downloadURL'" I understand that in firebase 5 to get the url from storage you need to call downloadURL on storage reference, not metadata. I have tried multiple ways and examples, but it all leads to errors.screenshot of error

 @IBOutlet weak var photo: UIImageView!
@IBOutlet weak var captionTextView: UITextView!
@IBOutlet weak var removeButton: UIBarButtonItem!
@IBOutlet weak var shareButton: UIButton!
var selectedImage: UIImage?
override func viewDidLoad() {
    super.viewDidLoad()

    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleSelectPhoto)); photo.addGestureRecognizer(tapGesture)
    photo.isUserInteractionEnabled = true
}
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    handlePost()
}

func handlePost() {
    if selectedImage != nil {
       self.shareButton.isEnabled = true
        self.removeButton.isEnabled = true
        self.shareButton.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
    }else{
        self.shareButton.isEnabled = false
        self.shareButton.backgroundColor = .lightGray
        self.removeButton.isEnabled = false


    }
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    view.endEditing(true)

}
@objc func handleSelectPhoto() {
    let pickerController = UIImagePickerController()
    pickerController.delegate = self
    present(pickerController, animated: true, completion: nil)

}
@IBAction func shareButton_TouchUpInside(_ sender: Any) {
    view.endEditing(true)
    let hud = JGProgressHUD(style: .dark)
    hud.textLabel.text = "Loading"
    hud.show(in: self.view)
    hud.dismiss(afterDelay: 3.0)

    if let profileImg = self.selectedImage, let imageData = UIImageJPEGRepresentation(profileImg, 0.1) {
        let photoIdString = NSUUID().uuidString
    let storageRef = Storage.storage().reference(forURL: ".......").child("posts").child(photoIdString)
        storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
            if error != nil {
                return
            }

            //let photoUrl = url?.absoluteString
            let photoUrl = metadata?.downloadURL()?.absoluteString


            self.sendDataToDatabase(photoUrl: photoUrl!)
    }
    )}
}
@IBAction func remove_TouchUpInside(_ sender: Any) {
   clean()
   handlePost()
}
func sendDataToDatabase(photoUrl: String) {
    let ref = Database.database().reference()
    let postsReference = ref.child("posts")
     let newPostId = postsReference.childByAutoId().key

    let newPostReference =  postsReference.child(newPostId)
    newPostReference.setValue(["photoUrl": photoUrl, "caption": captionTextView.text!], withCompletionBlock: {
        (error, ref) in
        if error != nil {
            ProgressHUD.showError(error!.localizedDescription)
            return
        }
        ProgressHUD.showSuccess("Success")
        self.clean()
      self.tabBarController?.selectedIndex = 0 // switches user back to selected tabbar 0 = first 1 = second etc.
    })

}
func  clean() {
    self.captionTextView.text = ""
    self.photo.image = UIImage(named:"placeholder-photo")
    self.selectedImage = nil
  }
}
 extension CameraViewController: UIImagePickerControllerDelegate, 
UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, 
didFinishPickingMediaWithInfo info: [String : Any]) {
    print("did finish picking media")
    if let image = info["UIImagePickerControllerOriginalImage"] 
as? UIImage {
        selectedImage = image
        photo.image = image
    }
    // profileImage.image = infoPhoto
    dismiss(animated: true, completion: nil)
 }
}
1

1 Answers

0
votes
import UIKit
import ProgressHUD
import FirebaseStorage
import FirebaseDatabase

class CameraViewController: UIViewController {

    @IBOutlet weak var photo: UIImageView!
    @IBOutlet weak var shareButton: UIButton!
    @IBOutlet weak var captionTextView: UITextView!

    @IBOutlet weak var removeButton: UIBarButtonItem!
    var selectedImage: UIImage?

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture                           = UITapGestureRecognizer(target: self, action: #selector(self.handleSelectPhoto))
        photo.addGestureRecognizer(tapGesture)
        photo.isUserInteractionEnabled           = true
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
         handlePost()
    }


    func handlePost(){
        if selectedImage != nil {
            self.shareButton.isEnabled          = true
            self.removeButton.isEnabled         = true
            self.shareButton.backgroundColor    = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
        } else {
            self.shareButton.isEnabled          = false
            self.removeButton.isEnabled         = false
            self.shareButton.backgroundColor    = .lightGray

        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }

    @objc func handleSelectPhoto(){
        let pickerController                   = UIImagePickerController()
        pickerController.delegate              = self
        present(pickerController, animated: true, completion: nil)

    }


    // Share photos to the storage database
    @IBAction func shareButton_TouchUpInside(_ sender: Any) {
        view.endEditing(true)
        ProgressHUD.show("Please wait...", interaction: false)
        if let profileImg                     = self.selectedImage, let photoData = profileImg.jpegData(compressionQuality: 0.1) {

            let photoIdString                 = NSUUID().uuidString
            print(photoIdString)
            let storageRef                    = Storage.storage().reference(forURL:Config.STORAGE_ROOT_REF).child("Posts").child(photoIdString)
            storageRef.putData(photoData, metadata: nil, completion: { (metadata, error) in
                if error != nil  {
                    ProgressHUD.showError(error!.localizedDescription)

                    return
                }
                let photoUrl = metadata?.downloadURL()?.absoluteString
                self.sendDataToDatabase(photoUrl: photoUrl!)
            })

        } else {
            ProgressHUD.showError("Profile image can't be empty")
        }
    }


    @IBAction func remove_touchUpInside(_ sender: Any) {

        clean()
        handlePost()
    }

    func sendDataToDatabase(photoUrl:String){

            let ref                        = Database.database().reference()
            let postsReference             = ref.child("posts")
            let newPostId                  = postsReference.childByAutoId().key
            let newPostReference           = postsReference.child(newPostId)
        newPostReference.setValue(["photoUrl": photoUrl, "caption": captionTextView.text!], withCompletionBlock: {
            (error, ref) in
            if error != nil{
                ProgressHUD.showError(error!.localizedDescription)
                return
            }
            ProgressHUD.showSuccess("Success")
            self.clean()
            self.tabBarController?.selectedIndex  = 0

        })
    }

    func clean(){
        self.captionTextView.text       = ""
        self.photo.image                = UIImage(named: "placeholder-img")
        self.shareButton                = nil
    }
}

extension CameraViewController : UIImagePickerControllerDelegate, UINavigationControllerDelegate {

   func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        print("did Finish picking media")
       if let chosenImage = info[.originalImage] as? UIImage {

        selectedImage                  = chosenImage
        photo.image                    = chosenImage

        }

        dismiss(animated: true, completion: nil)
    }
}

Use Above code, it will successfully upload the image and post that to the Firebase Database