Reputation: 1301
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) in didSelectItem
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 where posts[indexPath.row]
comes from.
Upvotes: 5
Views: 13217
Reputation: 879
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.
Upvotes: 1
Reputation:
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.
Upvotes: 9