How to delete a child from Firebase (Swift)
Solution 1
This should work.
func deletePost() {
let uid = FIRAuth.auth()!.currentUser!.uid
let storage = FIRStorage.storage().reference(forURL: "gs://cloudcamerattt.appspot.com")
// Remove the post from the DB
ref.child("posts").child(selectedPost.postID).removeValue { error in
if error != nil {
print("error \(error)")
}
}
// Remove the image from storage
let imageRef = storage.child("posts").child(uid).child("\(selectedPost.postID).jpg")
imageRef.delete { error in
if let error = error {
// Uh-oh, an error occurred!
} else {
// File deleted successfully
}
}
}
Also .childByAutoId().key
generates a key to insert items into the DB. You can't use it get a reference to an existing item.
Solution 2
According to Firebase docs, you can also delete it by
specifying null as the value for another write operation such as set() or update()
You can use this technique with update() to delete multiple children in a single API call.
Related videos on Youtube
KingTim
Updated on June 04, 2022Comments
-
KingTim almost 2 years
I've been following a tutorial on making an instragram-esque app, and I'm having a lot of trouble figuring out how to delete a post, both from Firebase and from the feed. The image that the user selects or takes is uploaded to Firebase database with this function:
func uploadToFirebase() { AppDelegate.instance().showActivityIndicator() let uid = FIRAuth.auth()!.currentUser!.uid let ref = FIRDatabase.database().reference() let storage = FIRStorage.storage().reference(forURL: "gs://cloudcamerattt.appspot.com") let key = ref.child("posts").childByAutoId().key let imageRef = storage.child("posts").child(uid).child("\(key).jpg") let data = UIImageJPEGRepresentation(self.previewImage.image!, 0.6) let uploadTask = imageRef.put(data!, metadata: nil) { (metadata, error) in if error != nil { print(error!.localizedDescription) AppDelegate.instance().dismissActivityIndicator() return } imageRef.downloadURL(completion: { (url, error) in if let url = url { // how do I add date: NSDate in here? let feed = ["userID" : uid, "pathToImage" : url.absoluteString, "likes" : 0, "author" : FIRAuth.auth()!.currentUser!.displayName!, "postID" : key] as [String : Any] let postFeed = ["\(key)" : feed] ref.child("posts").updateChildValues(postFeed) AppDelegate.instance().dismissActivityIndicator() self.dismiss(animated: true, completion: nil) } }) } uploadTask.resume() }
Which ends up in Firebase looking like this:
Following a stack overflow answer I found, I tried to set up a delete function to be called when the delete button is pressed. This delete button is on a "photo detail" view, which the user gets to by tapping an image in the image feed - this photo detail view displays the image in a bigger size, along with some other info such as likes:
func deletePost(firstTree: String, childIWantToRemove: String) { let uid = FIRAuth.auth()!.currentUser!.uid let ref = FIRDatabase.database().reference() let storage = FIRStorage.storage().reference(forURL: "gs://cloudcamerattt.appspot.com") let key = ref.child("posts").childByAutoId().key let imageRef = storage.child("posts").child(uid).child("\(key).jpg") ref.child("posts").child(key).child("postID").removeValue { (error, ref) in if error != nil { print("error \(error)") } } }
And call the function here:
@IBAction func moreButtonPressed(_ sender: AnyObject) { let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) let destroyAction = UIAlertAction(title: "Delete", style: .destructive) { action in print(action) let ref = FIRDatabase.database().reference() let key = ref.child("posts").childByAutoId().key let firstTree = key let valueToRemove = "postID" self.deletePost(firstTree: firstTree, childIWantToRemove: valueToRemove) } alertController.addAction(destroyAction) alertController.addAction(cancelAction) self.present(alertController, animated: true) }
I'm not really understanding what I'm doing though, and needless to say tapping the delete button does essentially nothing. Can anyone show me how to fix the delete function so I can remove an image/post from firebase properly?
EDIT: I have
var selectedPost: Post!
in my PhotoDetailController, which is passed from the FeedViewController (image feed) indidSelectItem
like so:func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let photoDetailController = self.storyboard?.instantiateViewController(withIdentifier: "photoDetail") as! PhotoDetailController photoDetailController.selectedPost = posts[indexPath.row] present(photoDetailController, animated: true, completion: nil) }
So it has the index path. Another note about the above function is that
var posts = [Post]()
is instantiated in the FeedViewController, so that's whereposts[indexPath.row]
comes from.-
Admin about 7 yearsDo you have a post object in your detailView with the info of the current post in the detail view? Or any object that contains the information of the post (such as the ID)?
-
KingTim about 7 yearsHey Pieter yes I have a variable which holds the Post object and the index path of the selected image from the feed - check my edit, I put the code there to make it clearer.
-
-
KingTim about 7 yearsThank you so much! It worked perfectly. Looking at your code, this actually ended up being more straightforward than I thought, I was getting wrapped up in trying to figure out how to use the childByAutoID. Thanks again much appreciated!