1

I'm developing an app when user can login, in the user profile page, the user can choose an image profile for show in my app. This image is uploaded in Firebase Database and in stored in Firebase Storage. I want to the user can decide to delete his current image profile if he wants to. I can't find a way to do it, how can I delete his image from Firebase Storage, I use metadata in order to put it in Storage.

Here's my code for upload image in Firebase Storage and Firebase Database :

// Create a path in order to save the photo in Firebase Database
func setUser(img: String) {
    var userUid = Auth.auth().currentUser?.uid
    let userData = ["nickname": Auth.auth().currentUser?.displayName, "userImg": img]

    KeychainWrapper.standard.set(userUid!, forKey: "uid")
    let location =                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Database.database().reference().child("users").child(userUid!).child("pseudo")
    location.setValue(userData)
    dismiss(animated: true, completion: nil)
}

// Upload and put image profile in the Firebase Storage
func uploadImg() {
    name = Auth.auth().currentUser?.displayName
    userUid = Auth.auth().currentUser?.uid

    guard let img = userImagePicker.image, imageSelected == true else {
        print("Image needs to be selected")
        return
    }

    if let imgData = UIImageJPEGRepresentation(img, 0.2) {
        let imgUid = NSUUID().uuidString
        let metadata = StorageMetadata()
        metadata.contentType = "image/jpeg"

        Storage.storage().reference().child(imgUid).putData(imgData, metadata: metadata) { (metadata, error) in
            if error != nil {
                print("Didn't upload image in Firebase Storage")
                self.isUploaded = false
            } else {
                print("Uploaded in Firebase Storage")
                self.isUploaded = true
                let downloadURL = metadata?.downloadURL()?.absoluteString
                if let url = downloadURL {
                    self.setUser(img: url)
                    self.downloadPhoto(user: self.name)
                }
            }
        }
    }
}

// The alert Controller (user can choose to take a photo with Camera or choose an image in his library then I use UIImagePickerController in order to display the image on a UIImageView)
@IBAction func actionButton(_ sender: Any) {
let attributedString = NSAttributedString(string: "User photo", attributes: [
    NSFontAttributeName : UIFont.boldSystemFont(ofSize: 15),
    NSForegroundColorAttributeName : UIColor.black
    ])

let alertController = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
alertController.message = nil
alertController.setValue(attributedString, forKey: "attributedTitle")
alertController.addAction(UIAlertAction(title: "Take photo", style: .default, handler: self.takePhoto))
alertController.addAction(UIAlertAction(title: "Choose in Library", style: .default, handler: self.libraryPhoto))
alertController.addAction(UIAlertAction(title: "Show current photo", style: .default, handler: self.showPhoto))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
}

How can I delete this image if I add a button "Delete photo"? How can I retrieve this image in Firebase Storage? I'm not able to find the right image and delete it, and I really don't know how to create a folder in Firebase Storage, so all the users images are in the same section of the Storage and I can't retrieve the right image (imageUid).

  • I think you can make a folder for images like this: `Storage.storage().reference().child("YourImagesFolder").child(imgUid).putData(...` – 3stud1ant3 Sep 30 '17 at 16:40
  • Do you know if with a free account, I can create a folder because no folder is created in Firebase Storage –  Oct 01 '17 at 02:12

1 Answers1

2

To delete an image, you'll need to be able to recreate the path to the image. This means knowing the file name of the image.

When you save your images at the moment, you're assigning each one a random UUID and chucking in the root of the bucket, which isn't helpful from an organisational standpoint. I would create a folder for each user and store the image as something helpful (like profilePic.jpg), as follows:

func uploadImg() {
    name = Auth.auth().currentUser?.displayName
    userUid = Auth.auth().currentUser?.uid

    guard let img = userImagePicker.image, imageSelected == true else {
        print("Image needs to be selected")
        return
    }

    if let imgData = UIImageJPEGRepresentation(img, 0.2) {
        let metadata = StorageMetadata()
        metadata.contentType = "image/jpeg"

        // create reference to image location
        let profilePicRef = Storage.storage().reference().child("\(userUid!)/profilePic.jpg")
        // upload image
        profilePicRef.putData(imgData, metadata: metadata) { (metadata, error) in
            if error != nil {
                print("Didn't upload image in Firebase Storage")
                self.isUploaded = false
            } else {
                print("Uploaded in Firebase Storage")
                self.isUploaded = true
                let downloadURL = metadata?.downloadURL()?.absoluteString
                if let url = downloadURL {
                    self.setUser(img: url)
                    self.downloadPhoto(user: self.name)
                }
            }
        }
    }
}

Now we can easily find the profile picture, we can easily delete it:

func deleteProfilePic() {
    guard let userUid = Auth.auth().currentUser.uid else {
        return
    }
    let pictureRef = Storage.storage().reference().child("\(userUid)/profilePic.jpg")
    pictureRef.delete { error in
        if let error = error {
            // Uh-oh, an error occurred!
        } else {
            // File deleted successfully
        }
    }
}
Bradley Mackey
  • 6,777
  • 5
  • 31
  • 45
  • Thank you for your answer, but no folder is created, maybe only with a Firebase subscription is possible ? –  Oct 01 '17 at 02:11
  • Your code works but why I can't see the folder for each user in Firebase Storage. It seems created but can't see it –  Oct 02 '17 at 19:01
  • @Giggs maybe give the console a bit of time to update? They should be showing. – Bradley Mackey Oct 02 '17 at 19:04
  • Yes thank you, in fact it was hide because to much photo on my storage so I just deleted the photo I uploaded for tests then I was able to see the folders for each users I tested. Thank you very much. –  Oct 04 '17 at 16:12