从Firebase删除表视图单元格

时间:2017-07-13 00:47:34

标签: ios swift firebase firebase-realtime-database firebase-authentication

我有一个表格,其中包含已登录用户和该应用的其他用户的附加消息。当我滑动单元格时,我希望能够从Firebase中删除它,也可以从tableView中自动删除它。我设法从Firebase中删除了单元格,但没有从tableView中删除。这是消息最初加载到tableView中的方式:

  func loadData()
    {
        guard let uid = FIRAuth.auth()?.currentUser?.uid else {
            return
        }
   FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in

            if let postsDictionary = snapshot .value as? [String: AnyObject] {

                for post in postsDictionary {
                    let messages = post.value as! [String: AnyObject]
                    for (id, value) in messages {
                        let info = value as! [String: AnyObject]


                        let convoId = info["convoId"]
                        let toId = info["ReceiverId"] as! String!
                        let fromId = info["senderId"] as! String!


                        if (toId == self.loggedInUserUid  || fromId == self.loggedInUserUid) {

        let refs = FIRDatabase.database().reference().child("user-messages").child(convoId as! String).child(uid)
        refs.observe(.childAdded, with: { (snapshot) in


            self.messageId = snapshot.key



        let ref = FIRDatabase.database().reference().child("messages").child(convoId as! String).child(self.messageId!)

                            ref.observeSingleEvent(of: .value, with: { (snapshot) in


            if let dictionary = snapshot.value as? [String: AnyObject] {
                let message = Message(dictionary: dictionary)


                if let receiver = message.convoId {
                    self.messagesDictionary[receiver] = message

                    self.messages = Array(self.messagesDictionary.values)
                    print(self.messages)
                    self.messages.sort(by: { (message1, message2) -> Bool in


                        return (message1.timestamp?.int32Value)! > (message2.timestamp?.int32Value)!

                    })
                }

                //this will crash because of background thread, so lets call this on dispatch_async main thread
                DispatchQueue.main.async(execute: {
                    self.MessageTableView.reloadData()
                })
            }

        }, withCancel: nil) })}
                    }

                }}})

    }

以下是我在Firebase中执行删除功能并尝试在tableView中执行删除功能的方法:

  override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

        if editingStyle == .delete {

        guard let uid = FIRAuth.auth()?.currentUser?.uid else {
            return
        }

        let message = messages[(indexPath.row)]


       self.deletemessage = message.convoId


        FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in

            if let postsDictionary = snapshot .value as? [String: AnyObject] {

                for post in postsDictionary {
                    let messages = post.value as! [String: AnyObject]
                    for (id, value) in messages {
                        let info = value as! [String: AnyObject]


                        let convoId = info["convoId"]

        let ref = FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid)
        ref.observe(.childAdded, with: { (snapshot) in

            self.messageId = snapshot.key

            FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid).child( self.messageId!).removeValue(completionBlock: { (error, ref) in
                if error != nil {
                    print("error \(error)")
                }else{



                }})})}}}})

            self.messages.remove(at: indexPath.row)
            self.MessageTableView.deleteRows(at: [indexPath], with: .automatic)

        }
    }

它从tableView中删除但崩溃并在self.messages.remove(at: indexPath.row)致命错误上给出错误:索引超出范围。

1 个答案:

答案 0 :(得分:0)

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {

            let state = id[indexPath.row] //it store the child key to be removed. here id array is not displayed but used as backend process

            print(state) // (Not required)

            names.remove(at: indexPath.row) //Remove the selected name from array used in TableView that is displayed in cell

            tableView.deleteRows(at: [indexPath], with: .fade) // TableView Animation 

            Database.database().reference().child("artists").child(id[indexPath.row]).removeValue() // remove the child referred using id from database

            id.remove(at: indexPath.row) // removing selected if from id array locally 

        }
    }

请尝试以下代码在您的情况下,请让我知道问题仍然存在

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

if editingStyle == .delete {

guard let uid = FIRAuth.auth()?.currentUser?.uid else {
    return
}
let message = messages[(indexPath.row)]

self.deletemessage = message.convoId

FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in
    if let postsDictionary = snapshot .value as? [String: AnyObject] {
        for post in postsDictionary {
            let messages = post.value as! [String: AnyObject]
            for (id, value) in messages {
                let info = value as! [String: AnyObject]
                let convoId = info["convoId"]
                let ref = FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid)
                ref.observe(.childAdded, with: { (snapshot) in

                    self.messageId = snapshot.key

                    FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid).child( self.messageId!).removeValue(completionBlock: { (error, ref) in
                        if error != nil {
                            print("error \(error)")
                        }
                    })
                })
            }
        }}})
    self.messages.remove(at: indexPath.row)
    self.MessageTableView.deleteRows(at: [indexPath], with: .automatic)
}
}

尝试这种情况会发生,因为您正在删除值正确但在处理程序下甚至在我的项目中导致错误。消息中的数据是从数据库加载的,因此如果不从数据库中删除值,即使从数组中删除,它也会再次更新。所以请试试这段代码