Swift 3,Firebase完成处理程序执行两次

时间:2017-09-03 21:09:40

标签: firebase swift3 firebase-realtime-database completionhandler

我的用例 - 我有从Firebase获取的项目列表。以下是我从 HomeViewController调用的 loadItems()函数 -  viewDidLoad()并使用获取的数据更新tableView。

func loadItems() {

    Database.database().reference().child("items").observe(.value, with: { snapshot in
        var fetchedItems = [Item]()
        guard let receivedvalue = snapshot.value as? [String: Any] else     {
            print("Received null")
            return
        }
        print(receivedvalue)

        for (key, value) in receivedvalue {
            let item = Item(id: Int(key)!, json: value as! [String : Any])
            fetchedItems.append(item!)
        }
        self.items = fetchedItems
        self.tableView.reloadData()
    })
}

我正在保存一个项目并从CreateViewController返回到HomeViewController,我是 - 在Firebase中保存项目,将项目附加到预取数组,重新加载tableView。

func addItem(item: Item?) {
    rootRef = Database.database().reference()

    let id = String(describing: item.id!)
    let itemRef = self.rootRef.child("items").child(id)
    itemRef.setValue(["name": item.name!, "type": item.type!])

    items.append(item!)
    self.tableView.reloadData()
}

重新加载tableView后,它将进入firebase GET Call处理程序,该处理程序存在于loadItems()中。

当我在viewDidLoad()期间获取所有项目时,处理程序执行一次。有没有理由为什么第二次执行Firebase GET调用处理程序,即使我没有在创建工作流中调用loadItems()?

1 个答案:

答案 0 :(得分:0)

当使用 .observe(.value 时,它会向该节点添加一个观察者,对该节点的任何更改(添加,更改,删除)将触发代码在关闭。

如果您想离开观察者以便收到更改通知,那么正确的流程就是简单地将数据写入Firebase并让闭包加载数据并填充tableView。

然而,其缺点是.value会加载节点中的所有数据。您可能希望看一下为.childAdded,.childChanged和.childRemoved添加单独的观察者。这些只会加载已修改的节点。

如果您只想加载一次数据(例如,在启动时填充数据源),请使用一次触发的observeSingleEvent并且不会离开观察者。

然后将数据存储在Firebase中并手动将其添加到阵列并重新加载tableView。

请参阅文档Read Data Once部分。