2016-11-23 4 views
0

У меня есть 2 ссылки (по тому же пути), один из которых прослушивает отложенные ордера, а другой, который прослушивает завершенные заказы. Все для определенного места, которое пользователь может изменить.Firebase + Swift: removeAllObservers не работает?

Механизм Я использую в настоящее время заключается в следующем:

  1. Создать массив, который будет хранить Firebase ссылки
  2. Перед тем, как observe событие для отложенных ордеров, нажимной, что Firebase ссылка на мой массив
  3. До I observe событие для завершенных заказов, нажмите эту ссылку 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 

=== UPDATE === Я даже пытался ручки и он не работает:

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 = [] 
    } 
    } 
} 
+0

Мой первый вопрос; почему ты это делаешь? Когда вы добавляете наблюдателя, он продолжает наблюдать и будет называть закрытие связанного события. Сохранение ссылки на него в массиве не требуется. В этом случае любое событие, которое происходит в узле «Заказы», ​​будет уведомлять ваше приложение. – Jay

+0

Эй, Джей. Приложение используется следующим образом: пользователь выбирает местоположение и видит все заказы для этого местоположения. Когда заказ переключает местоположение, он должен теперь показывать только заказы на новое место, а не старое – Edmund

+0

. Похоже, вы наблюдаете .childAdded и .value для того же места? – Jay

ответ

0

Я думаю, что, возможно, я установил его? Так было, потому что я действительно наблюдаю за дочерним узлом этой ссылки, поэтому удаление всех наблюдателей для родительского узла ничего не делает, потому что вы должны удалить его на определенном узле, который вы наблюдаете.

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 = [] 
    } 

} 
Смежные вопросы