删除Firebase数据时遇到更新tableview行的麻烦

时间:2019-05-27 12:17:08

标签: swift firebase firebase-realtime-database tableview

在删除Firebase数据后尝试更新表视图的行时出了点问题。

下面是我使用的方法。

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in

        let cell = self.messages[indexPath.row]
        let b = cell.msgNo

        let action = MyGlobalVariables.refMessages.child(MyGlobalVariables.uidUser!)
        action.queryOrdered(byChild: "msgNo").queryEqual(toValue: b).observe(.childAdded, with: { snapshot in

            if snapshot.exists() { let a = snapshot.value as? [String: AnyObject]

                let autoId = a?["autoID"]

                action.child(autoId as! String).removeValue()

                self.messages.remove(at: indexPath.row)

                tableView.deleteRows(at: [indexPath], with: .automatic)
            } else {
                print("snapshot empty")
            }}) }
   ...
   return [delete, edit, preview]
}

最初,我在不包括行/*action.child(autoId as! String).removeValue()*/的情况下检查了整个逻辑,然后它可以正常工作并应删除行。但是,一旦我添加了这一行,它将从Firebase中删除数据,但是通过在现有

下添加新行,以奇怪的方式更新了tableview

Attached snapshot of my application with/without this line of code

1 个答案:

答案 0 :(得分:1)

我的猜测是,应用程序中的其他地方具有类似action .observe(.value的代码,该代码在表视图中显示数据。当您从数据库中删除节点时,填充数据库的代码将再次被触发,并将相同的数据(减去已删除的节点)再次添加到表视图中。

使用Firebase时,最好遵循command query responsibility segregation原则,这意味着您将修改数据的代码与显示数据的流程完全分开。这意味着删除数据的代码不应尝试更新表视图。所以更像是:

let action = MyGlobalVariables.refMessages.child(MyGlobalVariables.uidUser!)
action.queryOrdered(byChild: "msgNo").queryEqual(toValue: b).observe(.childAdded, with: { snapshot in
    if snapshot.exists() { let a = snapshot.value as? [String: AnyObject]
        let autoId = a?["autoID"]
        action.child(autoId as! String).removeValue()
    } else {
        print("snapshot empty")
    }}) }

以上所有操作是从数据库中删除选定的消息。

现在,您可以专注于观察者,并确保它只显示一次消息。有两种选择:

  1. 在您从数据库添加消息之前,请务必在您的self.messages完成处理程序被调用时清除.value。这是迄今为止最简单的方法,但是如果显示大量数据,可能会导致闪烁。
  2. 收听更细粒度的消息,例如.childAdded.childRemoved,并根据这些消息更新self.messages。这在您的代码中需要做更多的工作,但是当有许多消息时,将使UI更加平滑。