如何从 Firebase (Swift) 中删除一个孩子

Posted

技术标签:

【中文标题】如何从 Firebase (Swift) 中删除一个孩子【英文标题】:How to delete a child from Firebase (Swift) 【发布时间】:2017-03-12 15:19:22 【问题描述】:

我一直在关注有关制作 instragram 式应用程序的教程,但在弄清楚如何从 Firebase 和提要中删除帖子时遇到了很多麻烦。使用此功能将用户选择或拍摄的图像上传到 Firebase 数据库:

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

最终在 Firebase 中看起来像这样:

根据我找到的堆栈溢出答案,我尝试设置一个删除函数,以便在按下删除按钮时调用。此删除按钮位于“照片详细信息”视图上,用户可以通过点击图像馈送中的图像来访问该视图 - 此照片详细信息视图以更大的尺寸显示图像,以及一些其他信息,例如喜欢:

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

并在这里调用函数:

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

虽然我并没有真正理解我在做什么,而且不用说点击删除按钮基本上没有任何作用。谁能告诉我如何修复删除功能,以便我可以正确地从 Firebase 中删除图像/帖子?

编辑:我的 PhotoDetailController 中有 var selectedPost: Post!,它是从 didSelectItem 中的 FeedViewController(图像提要)传递的,如下所示:

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)

所以它有索引路径。关于上述函数的另一个注意事项是 var posts = [Post]() 是在 FeedViewController 中实例化的,所以这就是 posts[indexPath.row] 的来源。

【问题讨论】:

您的 detailView 中是否有一个 post 对象,其中包含详细视图中当前帖子的信息?或者任何包含帖子信息(如ID)的对象? 嘿 Pieter 是的,我有一个变量,它保存 Post 对象和来自提要的所选图像的索引路径 - 检查我的编辑,我把代码放在那里以使其更清晰。 【参考方案1】:

这应该可行。

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
    
  

.childByAutoId().key 还生成一个密钥以将项目插入数据库。您不能使用它来获取对现有项目的引用。

【讨论】:

非常感谢!它工作得很好。查看您的代码,这实际上比我想象的更简单,我正忙于弄清楚如何使用 childByAutoID。再次感谢非常感谢!【参考方案2】:

根据 Firebase 文档,您也可以通过

将其删除

将 null 指定为另一个写入操作的值,例如 set() 或更新()

您可以将此技术与 update() 一起使用,以在单个 API 调用中删除多个子项。

【讨论】:

以上是关于如何从 Firebase (Swift) 中删除一个孩子的主要内容,如果未能解决你的问题,请参考以下文章

如何从特定的 UICollectionViewCell 中删除 firebase 子节点 - Swift

如何通过swift3在firebase中24小时内删除数据

Firebase + Swift:无法删除 tableView 中的行

如何将图像从Firebase下载到Swift,然后更快地在UIImageView中显示?

如何使用 Swift 删除 Firebase 上超过 30 分钟的数据? [复制]

如何从 swift 代码中应用 firebase 数据库安全规则