Проблемы с обновлением строк таблицы при удалении данных Firebase - PullRequest
0 голосов
/ 27 мая 2019

что-то идет не так при попытке обновить строки таблицы после удаления данных 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, но представление таблицы обновляется странным образом, добавляя новые строки под существующими

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

1 Ответ

1 голос
/ 27 мая 2019

Я предполагаю, что где-то еще в вашем приложении у вас есть код типа action .observe(.value, который показывает данные в табличном представлении. Когда вы удаляете узел из базы данных, код, который заполняет базу данных, снова запускается и добавляет те же данные (за исключением удаленного вами узла) в табличное представление снова.

При работе с Firebase лучше всего следовать принципу разделения ответственности по запросу команды , что означает, что вы храните код, который изменяет данные, полностью отдельно от потока, который отображает данные. Это означает, что ваш код, удаляющий данные, не должен пытаться обновить табличное представление. Так что-то вроде:

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, основываясь на них. Это больше работает в вашем коде, но приведет к более гладкому пользовательскому интерфейсу, когда много сообщений.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...