用户ID更改时处理Firebase观察者?

时间:2018-02-10 09:03:51

标签: ios swift firebase firebase-realtime-database

我在帮助器类中使用此函数来获取用户的行程。它一直在倾听新的变化:

import Foundation
import Firebase

class APICardService: NSObject {
    class func fetchTrips(forID userID: String, completion: @escaping ([Trip]) -> Void) {
        let path = "users/\(userID)/trips"
        Database.database().reference().child(path).queryOrdered(byChild: "timestamp").observe(.value) { (snapshot) in
            var trips = [Trip]()
            for child in snapshot.children {
                if let child = child as? DataSnapshot {
                    if let dict = child.value as? [String: Any] {
                        let trip = Trip(key: child.key, dbValues: dict)
                        trips.append(trip)
                    }
                }
            }
            completion(trips)
        }
    }
}

class MyViewController: UIViewController {
    // but what if the userID changes? I have no way to stop the current observer and start a new one
    internal func fetchCards() {
        guard let userID = APIAuthService.getUserID() else { return }
        APICardService.fetchTrips(forID: userID) { trips in
            self.trips = trips.reversed() // show most recent first
            self.addAnnotations(for: trips)
            self.collectionView.reloadData()
        }
    }
}

问题在于,每当用户注销并登录到新帐户时,此观察者仍将监听数据中的新值更改,但由于userID已更改,因此无法正常工作。我该如何处理?我可以以某种方式删除观察者,但这很复杂,因为我们在一个单独的类中,我不知道如何处理它。

2 个答案:

答案 0 :(得分:1)

正如@PrashantTukadiya所说。 尝试做这样的事情:

struct User {
    var id: String
    ...
}

class UserHolder {
    static var shared: UserHolder = UserHolder() // Singleton

    var currentUser: User? {
        willSet {
            // Remove all the registered firebase handlers associated with the user
            firebaseHandles.forEach({ $0.0.removeObserver(withHandle: $0.1) })
        }
    }

    var firebaseHandles: [(DatabaseReference, UInt)] = []

    // Note: Try to add all the firebase handles you register to "firebaseHandles"
    //   array. The more adequate solution is to make this class register
    //   the listeners, not all other classes.
}

答案 1 :(得分:1)

在班级APICardService中创建这些全局变量

static var refHandle:DatabaseHandle?  = nil
static var ref:DatabaseReference? = nil

在您的方法func fetchTrips(forID userID: String, completion: @escapin

分配像这样的全局变量

let path = "users/\(userID)/trips"
ref = Database.database().reference().child(path)
refHandle =  ref?.queryOrdered(byChild: "timestamp").observe(.value) { (snapshot) in

现在你有了观察者的参考资料

只需在您的课程中添加以下方法

class func removeObserverForFetchTrip() {
        if let refHandleValue = refHandle {
            ref?.removeObserver(withHandle: refHandleValue)
        }
}

当用户注销时,只需调用此方法

希望它有用