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

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

问题描述:

我的用例 - 我有从Firebase获取的项目列表。下面是loadItems()函数,我打电话HomeViewController - viewDidLoad()和更新tableView与获取的数据。Swift 3,Firebase完成处理程序执行两次

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,我 - 保存项火力地堡,追加的项目预取阵列,重装的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后,它是)要在火力地堡GET调用句柄这是目前在loadItems(。

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

+0

当您从CreateViewController返回时,您的viewDidLoad会被调用吗? – 3stud1ant3

+0

如果使用addItem函数将项目添加到'items'节点,则该节点的值将发生变化,因此将再次执行闭包。 –

+0

@JenPerson在使用observeSingleEvent之后,闭包只执行一次。问题解决了。谢谢! – Rajiv

当使用.observe(.value的,它增加了观察者到该节点和任何变化到该节点(增加,改变,删除)将触发代码在封闭。

如果你想离开观察者,这样你就可以得到变化的通知,正确的流程是简单地将数据写入Firebase并让封闭加载数据并填充tableView。

然而,其缺点是.value加载节点中的所有数据您可能想要查看为.childAdded,.childChanged和.childRe添加单独的观察者移动。那些只会加载修改过的节点。

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

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

请参阅文档Read Data Once部分。

+0

使用observeSingleEvent,闭包只执行一次。感谢您的详细解释! – Rajiv