Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uploading Images from UIImage Picker onto new Firebase (Swift)

I have a UIImagePicker set up within my app that works fine. I would like to upload a profile picture to Firebase when my UIImage picker has been chosen. Here is my function for when a picture has been selected.

    //image picker did finish code
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

    let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    profilePic.contentMode = .ScaleAspectFill
    profilePic.image = chosenImage
    profilePic.hidden = false
    buttonStack.hidden = true
    changeButtonView.hidden = false
    self.statusLabel.text = "Here is Your Profile Picture"

    dismissViewControllerAnimated(true, completion: nil)


}

The new documentation states that we need to declare a NSURl in order to upload a file. Here is my attempt to find the NSURL of the given file, but it doesn't work. Here is the documentation and a link to it:https://firebase.google.com/docs/storage/ios/upload-files#upload_from_data_in_memory

// File located on disk
let localFile: NSURL = ...
// Create a reference to the file you want to upload
let riversRef = storageRef.child("images/rivers.jpg")

// Upload the file to the path "images/rivers.jpg"
let uploadTask = riversRef.putFile(localFile, metadata: nil) { metadata, error in
  if (error != nil) {
    // Uh-oh, an error occurred!
  } else {
    // Metadata contains file metadata such as size, content-type, and download URL.
    let downloadURL = metadata!.downloadURL
  }
}

Here is my attempt for retrieving the NSURL of the UIImagePicker:

//image picker did finish code
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        //getting the object's url
        let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
        let imageName = imageUrl.lastPathComponent
        let documentDir = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String;
        let photoUrl = NSURL(fileURLWithPath: documentDir)
        let localPath = photoUrl.URLByAppendingPathComponent(imageName!)
        self.localFile = localPath

        profilePic.contentMode = .ScaleAspectFill
        profilePic.image = chosenImage
        profilePic.hidden = false
        buttonStack.hidden = true
        changeButtonView.hidden = false
        self.statusLabel.text = "Here is Your Profile Picture"

        dismissViewControllerAnimated(true, completion: nil)


    }

I believe that I am also running into difficulties if the image was taken from the camera instead of the gallery since it is not saved on the device yet. How do I find this image/snapshots's NSURL?

like image 966
Abdelkader Laraichi Avatar asked Jun 13 '16 01:06

Abdelkader Laraichi


People also ask

What is uiimagepickercontroller in iOS?

For example, Facebook, Twitter and WhatsApp, etc. Apple provides a simple-to-use tool UIImagePickerController to allow developer to implement this feature within app in an easy way. Developer can define the media type (photo or video) and the source (user’s album or camera) of file.

Which photo types can be supported by uiimagepickerviewcontroller?

Not all photo types can be supported by UIImagePickerViewController. For example, panorama, live photos, time-lapse and slow motion UIImagePickerViewController provides an easy to use API for app user to select either photo or video from device. Media files can be selected or captured from Moments ,album or camera.

How to handle errors during uploading files to cloud storage for Firebase?

After a successful upload, we can fetch the download URL of the uploaded image and then fetch it with any image loader, e.g. Kingfisher. There could be errors during uploading files to Cloud Storage for Firebase at both server and client sides. We can handle the errors with the observe function.


1 Answers

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
                })
            }
        })
like image 114
Johnny Hsieh Avatar answered Sep 26 '22 07:09

Johnny Hsieh