user8381604
user8381604

Reputation:

How to delete a photo from Firebase Storage

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).

Upvotes: 1

Views: 3029

Answers (1)

Bradley Mackey
Bradley Mackey

Reputation: 7668

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
        }
    }
}

Upvotes: 2

Related Questions