Swift 中的完成处理程序 Firebase 观察者

Posted

技术标签:

【中文标题】Swift 中的完成处理程序 Firebase 观察者【英文标题】:Completion handler Firebase observer in Swift 【发布时间】:2017-09-14 22:34:50 【问题描述】:

我正在为一个返回对象列表的函数创建一个完成处理程序。当它第一次返回值时,它运行良好。但是,当 Firebase 数据库发生任何更改并再次调用观察时,数组大小会增加一倍。为什么会翻倍?

func getStadiums(complition: @escaping ([Stadium]) -> Void)
  var stadiums: [Stadium] = []
  let stadiumRef = Database.database().reference().child("Stadium")
  stadiumRef.observe(.value, with:  (snapshot) in
    for snap in snapshot.children 
      guard let stadiumSnap = snap as? DataSnapshot else 
        print("Something wrong with Firebase DataSnapshot")
          complition(stadiums)
          return
      
      let stadium = Stadium(snap: stadiumSnap)
      stadiums.append(stadium)
    
    complition(stadiums)
  )

然后像这样打电话

getStadiums() stadiums
  print(stadiums.count) // count gets doubled up after every observe call

【问题讨论】:

【参考方案1】:

您使用的代码在观察者之外声明stadiums。这意味着每当对数据库引用的值进行更改时,您都会将数据附加到 stadiums 而不清除之前的内容。请确保在再次附加快照之前从 stadiums 中删除数据:

func getStadiums(complition: @escaping ([Stadium]) -> Void)
  var stadiums: [Stadium] = []
  let stadiumRef = Database.database().reference().child("Stadium")
  stadiumRef.observe(.value, with:  (snapshot) in
    stadiums.removeAll() // start with an empty array
    for snap in snapshot.children 
      guard let stadiumSnap = snap as? DataSnapshot else 
        print("Something wrong with Firebase DataSnapshot")
          complition(stadiums)
          return
      
      let stadium = Stadium(snap: stadiumSnap)
      stadiums.append(stadium)
    
    complition(stadiums)
  )

【讨论】:

【参考方案2】:

stadiumRef.observe(.value, with: (snapshot) in ... 这一行实际上添加了一个观察者,每次更改体育场数据时都会调用该观察者。

因为您使用getStadiums() stadiums ... 调用了它两次,所以添加的观察者总数将是 2。

这使得stadiums.append(stadium) 在第二次调用中被调用了两次。

我的建议是使用一次stadiumRef.observe(),而不是从getStadiums() 调用它。

【讨论】:

【参考方案3】:

如下创建模型

class OrderListModel: NSObject 
    var Order:String?
    var Date:String?

在视图控制器中使用以下代码,您应该能够在 tableview 中看到内容

func getOrdersData()  
    self.orderListArr.removeAll()
    let ref = Database.database().reference().child(“users”).child(user).child("Orders")

        ref.observe(.childAdded, with:  (snapshot) in
            print(snapshot)
            guard let dictionary = snapshot.value as? [String : AnyObject] else 
                return
            

            let orderObj = OrderModel()
            orderObj.Order = dictionary[“Order”] as? String
            orderObj.Date = dictionary[“Date”] as? String

            self.orderListArr.append(orderObj)
            self.tableView.delegate = self
            self.tableView.dataSource = self
            self.tableView.reloadData()

        , withCancel: nil)

【讨论】:

【参考方案4】:
func ListenForChildrenAdded() 

let registerToListenTo = "YourPathHere"

ref.child(registerToListenTo).observeSingleEvent(of: .value)  (snapshot) in
    
    let initialChildren = snapshot.childrenCount
    var incrementer = 0
    
    ref.child(registerToListenTo).observe(.childAdded, with:  (snapshot) in
        
        incrementer += 1
        print("snapshot: \(snapshot.key) #\(incrementer)")

        if incrementer == initialChildren 
            print("-> All children found")
         else if incrementer > initialChildren 
            print("-> Child Was Added - Run Some Code Here")
        
        
    )

【讨论】:

以上是关于Swift 中的完成处理程序 Firebase 观察者的主要内容,如果未能解决你的问题,请参考以下文章

使用 Firebase 的 Swift 完成处理程序

如何使用 swift 和 firebase 正确使用完成处理程序?

Firebase Swift 3 完成处理程序 Bool

Swift 4 完成处理程序:数组保持为空

Swift 完成处理程序 - 转义尾随闭包

完成处理程序没有被调用为假定的 Swift