swift - Firebase + swift : removeAllObservers not working?

标签 swift firebase firebase-realtime-database

我有 2 个引用(指向同一路径),一个用于监听挂单,另一个用于监听已完成的订单。全部针对特定位置,用户可以更改该位置。

我现在使用的机制是这样的:

  1. 创建一个用于存储 Firebase 引用的数组
  2. 观察挂单事件之前,将该 Firebase 引用推送到我的数组中
  3. 观察已完成订单的事件之前,将该 Firebase 引用推送到我的数组中
  4. 当用户切换位置时,​​删除数组中所有引用的所有观察者。清空数组并开始监听新位置中的待处理/已完成订单(步骤 2 和 3)

我的代码如下所示:

struct Firebase {

  private let ORDERS_PATH = "locations-orders"

  private static var references = [FIRDatabaseReference]()

  static func observePendingOrders(lId: String, f: @escaping (AppState.Order) -> () ) {
    print("observing orders for \(ORDERS_PATH)/\(lId)")

    let pendingOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)")
    self.references.append(pendingOrdersReference)

    pendingOrdersReference
      .child(dateKeyToday())
      .queryOrdered(byChild: "created_at")
      .observe(.childAdded, with: { firebaseSnapshot in
        ...

        print("order received for \(ORDERS_PATH)/\(lId)")
      }
    )
  }

  static func fetchCompletedOrders(lId: String, f: @escaping ([AppState.Order]) -> () ) {
    print("observing completed orders for \(lId)")

    let completedOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)")
    self.references.append(completedOrdersReference)

    completedOrdersReference
      .child(dateKeyToday())
      .queryOrdered(byChild: "status_updated_at")
      .observe(.value, with: { firebaseSnapshot in
        ...
      }
    )
  }

  static func removeAllOrderObservers() {
    for reference in references {
      print("removing reference \(reference)")
      reference.removeAllObservers()
    }
    self.references = []
  }

}

但是,当我记录我正在监视的订单的位置时,看起来即使在我切换位置后,旧观察者仍在监听订单。这是我的日志:

observing orders for locations-orders/9RC4H9ZAE457E // first location
observing completed orders for 9RC4H9ZAE457E
removing reference https://mydb-123.firebaseio.com/locations-orders/9RC4H9ZAE457E // switch locations, remove all existing observers for location 9RC4H9ZAE457E
removing reference https://mydb-123.firebaseio.com/locations-orders/9RC4H9ZAE457E
observing orders for locations-orders/1JS53G0TT5ZQD // start listening for orders in new location. notice the new id: 1JS53G0TT5ZQD
observing completed orders for 1JS53G0TT5ZQD
order received for locations-orders/9RC4H9ZAE457E // <-- why is this still showing up?
order received for locations-orders/1JS53G0TT5ZQD
order received for locations-orders/1JS53G0TT5ZQD
order received for locations-orders/9RC4H9ZAE457E // <-- and this one too??
order received for locations-orders/1JS53G0TT5ZQD
order received for locations-orders/1JS53G0TT5ZQD

===更新=== 我什至尝试过 handle ,但没有用:

struct Firebase {

  private static var handles = [UInt]()
  private static var references = [FIRDatabaseReference]()

  static func observePendingOrders(lId: String, f: @escaping (AppState.Order) -> () ) {
    print("observing orders for \(ORDERS_PATH)/\(lId)")

    let pendingOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)")
    self.references.append(pendingOrdersReference)

    let handle = pendingOrdersReference
      .child(dateKeyToday())
      .queryOrdered(byChild: "created_at")
      .observe(.childAdded, with: { firebaseSnapshot in
        ...
      }
    )

    handles.append(handle)
  }

  static func fetchCompletedOrders(lId: String, f: @escaping ([AppState.Order]) -> () ) {
    print("observing completed orders for \(ORDERS_PATH)/\(lId)")

    let completedOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)")
    self.references.append(completedOrdersReference)

    let handle = completedOrdersReference
      .child(dateKeyToday())
      .queryOrdered(byChild: "status_updated_at")
      .observe(.value, with: { firebaseSnapshot in
        ...
      }
    )
    handles.append(handle)
  }

  static func removeAllOrderObservers() {
//    for reference in references {
//      print("removing reference \(reference)")
//      reference.removeAllObservers()
//    }
//    
    if !references.isEmpty {
      let ref = references[0]
      for handle in handles {
        print("removing handle \(handle)")
        ref.removeObserver(withHandle: handle)
      }
      self.references = []
    }
  }
}

最佳答案

我想我可能已经修复了它?所以这是因为我实际上是在该引用的子节点上进行观察,因此删除父节点的所有观察者不会执行任何操作,因为您必须在正在观察的特定节点上删除它。

let pendingOrdersReference = FIRDatabase
  .database()
  .reference(withPath: "\(ORDERS_PATH)/\(lId)")
  .child(dateKeyToday()) // <---- added this thing

这是我的最终解决方案,它似乎有效:

struct Firebase {
  private static var references = [FIRDatabaseReference]()

  static func observePendingOrders(lId: String, f: @escaping (AppState.Order) -> () ) {
    print("observing orders for \(ORDERS_PATH)/\(lId)")

    let pendingOrdersReference = FIRDatabase
      .database()
      .reference(withPath: "\(ORDERS_PATH)/\(lId)")
      .child(dateKeyToday())
    self.references.append(pendingOrdersReference)

    ...
  }

  static func fetchCompletedOrders(lId: String, f: @escaping ([AppState.Order]) -> () ) {
    print("observing completed orders for \(ORDERS_PATH)/\(lId)")

    let completedOrdersReference = FIRDatabase
      .database()
      .reference(withPath: "\(ORDERS_PATH)/\(lId)")
      .child(dateKeyToday())
    self.references.append(completedOrdersReference)

    ...

  }

  static func removeAllOrderObservers() {
    for reference in references {
      print("removing reference \(reference)")

      reference.removeAllObservers()
    }
    self.references = []
  }

}

关于swift - Firebase + swift : removeAllObservers not working?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40772101/

相关文章:

ios - 循环遍历 subview swift/ios

ios - 使用图像创建自定义 map 注释标注,从数组访问数据

ios - Swift:为用户搜索 Firebase 数据库

swift - 用户在线状态未自动更新

firebase - 添加 Firebase 数据、点和正斜杠

android - getContactsFromFirebase() 方法返回一个空列表

ios - Swift 返回错误 'Binary operator == cannot be applied to two EKSourceType operands'

swift - UI 快速更改,CoreAnimation : warning, 删除了未提交 CATransaction 的线程

android - 从身份验证列表向 Firebase 上的所有用户发送电子邮件

firebase - 使用 firebase resize images extension 动态调整图像大小