web-dev-qa-db-fra.com

Comment supprimer un enfant de Firebase (Swift)

J'ai suivi un tutoriel sur la création d'une application instragram-esque et j'ai beaucoup de difficulté à comprendre comment supprimer un message, à la fois de Firebase et du flux. L'image que l'utilisateur sélectionne ou prend est téléchargée dans la base de données Firebase avec cette fonction:

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

Ce qui finit par ressembler à Firebase:

 enter image description here

Après avoir trouvé une réponse au dépassement de capacité de la pile, j'ai essayé de configurer une fonction de suppression à appeler lorsque vous appuyez sur le bouton de suppression. Ce bouton de suppression se trouve sur une vue "Détail photo", à laquelle l'utilisateur accède en appuyant sur une image dans le flux d'images. Cette vue détaillée photo affiche l'image dans un format plus grand, avec d'autres informations telles que les préférences:

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

Et appelez la fonction ici:

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

Cependant, je ne comprends pas vraiment ce que je fais et il est inutile de dire que taper sur le bouton de suppression ne fait essentiellement rien. Quelqu'un peut-il me montrer comment corriger la fonction de suppression afin que je puisse supprimer correctement une image/publication de Firebase?

EDIT: J'ai var selectedPost: Post! dans mon PhotoDetailController, qui est transmis depuis le FeedViewController (flux d'image) dans didSelectItem comme ceci:

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

Donc, il a le chemin de l'index. Une autre remarque à propos de la fonction ci-dessus est que var posts = [Post]() est instancié dans FeedViewController, donc c'est de là que vient posts[indexPath.row].

5
KingTim

Cela devrait marcher.

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

De plus, .childByAutoId().key génère une clé pour insérer des éléments dans la base de données. Vous ne pouvez pas l'utiliser pour obtenir une référence à un élément existant.

7
user3476154

Selon la documentation Firebase, vous pouvez également le supprimer en 

spécifiant null comme valeur pour une autre opération d'écriture telle que set () ou update ()

Vous pouvez utiliser cette technique avec update () pour supprimer plusieurs enfants dans un seul appel d'API.

1
Kirill Kudaev