Uploading Images from UIImage Picker onto new Firebase (Swift)

Here is my method to upload and download the user profile photo from firebase storage:

    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
    userPhoto.image = image
    dismissViewControllerAnimated(true, completion: nil)
    var data = NSData()
    data = UIImageJPEGRepresentation(userPhoto.image!, 0.8)!
    // set upload path
    let filePath = "\(FIRAuth.auth()!.currentUser!.uid)/\("userPhoto")"
    let metaData = FIRStorageMetadata()
    metaData.contentType = "image/jpg"
    self.storageRef.child(filePath).putData(data, metadata: metaData){(metaData,error) in
        if let error = error {
            print(error.localizedDescription)
            return
        }else{
        //store downloadURL
        let downloadURL = metaData!.downloadURL()!.absoluteString
        //store downloadURL at database
    self.databaseRef.child("users").child(FIRAuth.auth()!.currentUser!.uid).updateChildValues(["userPhoto": downloadURL])
        }

        }
                   }

I also store the Image URL into firebase database and check if the user has a profile photo or you might get a crash:

 //get photo back
        
     databaseRef.child("users").child(userID!).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
            // check if user has photo
            if snapshot.hasChild("userPhoto"){
                // set image locatin
                let filePath = "\(userID!)/\("userPhoto")"
                // Assuming a < 10MB file, though you can change that
                self.storageRef.child(filePath).dataWithMaxSize(10*1024*1024, completion: { (data, error) in
                    
                    let userPhoto = UIImage(data: data!)
                    self.userPhoto.image = userPhoto
                })
            }
        })

Working in Swift 4.2

Here i am doing click on image i have added tapGesture then it open gallery then selected image that upload in Firebase and also i add textField Value Too i hope it helps you Thank You

import UIKit
import Firebase
class ViewController: UIViewController {

    @IBOutlet var myImageView: UIImageView!
    @IBOutlet var txtText: UITextField!
    var ref = DatabaseReference.init()
    var imagePicker = UIImagePickerController()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.ref = Database.database().reference()
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.openGalleryClick(tapGesture:)))
        myImageView.isUserInteractionEnabled = true
        myImageView.addGestureRecognizer(tapGestureRecognizer)
        myImageView.backgroundColor = UIColor.red
    }

    @objc func openGalleryClick(tapGesture: UITapGestureRecognizer){
        self.setupImagePicker()
    }

    @IBAction func btnSaveClick(_ sender: UIButton) {
         self.saveFIRData()
    }

    func saveFIRData(){
        self.uploadMedia(image: myImageView.image!){ url in
            self.saveImage(userName: self.txtText.text!, profileImageURL: url!){ success in
                if (success != nil){
                    self.dismiss(animated: true, completion: nil)
                }

            }
        }
    }


    func uploadMedia(image :UIImage, completion: @escaping ((_ url: URL?) -> ())) {
        let storageRef = Storage.storage().reference().child("myimage.png")
        let imgData = self.myImageView.image?.pngData()
        let metaData = StorageMetadata()
        metaData.contentType = "image/png"
        storageRef.putData(imgData!, metadata: metaData) { (metadata, error) in
            if error == nil{
                storageRef.downloadURL(completion: { (url, error) in
                    completion(url)
                })
            }else{
                print("error in save image")
                completion(nil)
            }
        }
    }

    func saveImage(userName:String, profileImageURL: URL , completion: @escaping ((_ url: URL?) -> ())){
        let dict = ["name": "Yogesh", "text": txtText.text!, "profileImageURL": profileImageURL.absoluteString] as [String : Any]
        self.ref.child("chat").childByAutoId().setValue(dict)
    }

}


extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate{

    func setupImagePicker(){
        if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
            imagePicker.sourceType = .savedPhotosAlbum
            imagePicker.delegate = self
            imagePicker.allowsEditing = true

            self.present(imagePicker, animated: true, completion: nil)
        }
    }

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

        let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        myImageView.image = image
        picker.dismiss(animated: true, completion: nil)
    }


}

Simple 2020 example

  1. Don't forget to add pod 'Firebase/Storage' to your podfile, and pod install

  2. Add two delegates to your class

    class YourScreen: UIViewController, 
      UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
  3. Storyboard, button, link to ...

    @IBAction func tapCameraButton() {
    let picker = UIImagePickerController()
    picker.allowsEditing = true
    picker.delegate = self
    present(picker, animated: true)
    }
    

    and then

    func imagePickerController(_ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
     guard let im: UIImage = info[.editedImage] as? UIImage else { return }
     guard let d: Data = im.jpegData(compressionQuality: 0.5) else { return }
    
     let md = StorageMetadata()
     md.contentType = "image/png"
    
     let ref = Storage.storage().reference().child("someFolder/12345678.jpg")
    
     ref.putData(d, metadata: md) { (metadata, error) in
         if error == nil {
             ref.downloadURL(completion: { (url, error) in
                 print("Done, url is \(String(describing: url))")
             })
         }else{
             print("error \(String(describing: error))")
         }
     }
    
     dismiss(animated: true)
    }
    

But where do you put the image?

At the code,

... .child("someFolder/12345678.jpg")

Almost inevitably,

• as the folder name use the user's id, the chat id, the feed id or a similar concept

• for the name, the only possibility is a uuid

Hence almost always

let f = chatId + "/" + UUID().uuidString + ".jpg"
let ref = Storage.storage().reference().child(f)