2016-11-23 11 views
0

2つの参照(同じパスへの参照)があります。一方は保留中のオーダーをリッスンし、もう1つは完了したオーダーをリッスンします。ユーザーが変更できる特定の場所のすべて。Firebase + Swift:removeAllObserversは機能しませんか?

私が今使っているメカニズムはこれです:

  1. 私が注文を保留中のイベントをobserve前に、私の配列
  2. にそのFirebase参照を押しFirebase参照
  3. を格納する配列を作成します。 observe完了したオーダーのイベントの前に、Firebaseリファレンスを自分のアレイにプッシュ
  4. ユーザーが場所を切り替えると、アレイ内のすべての参照についてオブザーバーをすべて削除します。私が注文の場所をログインしたときに、しかし

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

    :(2ステップと3)

私のコードは次のようになり、配列を空にし、新しい場所に注文を完了/保留中の待機を開始私が見ているのは、古い観察者が依然として注文を聞いている場所を切り替えた後も同じように見えます。ここに私のログがあります:

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

私の最初の質問です。なぜあなたはこれをやっている?オブザーバーを追加するとオブザーバーが観察され、関連付けられたイベントでクロージャーが呼び出されます。配列への参照を保持する必要はありません。この場合、Ordersノードで発生したすべてのイベントがアプリに通知されます。 – 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 = [] 
    } 

}