Search code examples
swiftxcodegoogle-cloud-firestorexcode10swift5

Getting old value of field in Firestore with Swift 5


I'm trying to get the old value of a field when it is changed in Firestore. Is there any way to access what the previous value of a field is after it is changed? Here is my current code, I want to access the old nickName under .modified and print out what the new nickName is and also the old one.

db.collection("cities").whereField("state", isEqualTo: "CA").addSnapshotListener { querySnapshot, error in
    guard let snapshot = querySnapshot else {
        print("Error fetching snapshots: \(error!)")
        return
    }
    snapshot.documentChanges.forEach { diff in
        if (diff.type == .added) {
            print("New city: \(diff.document.data())")
        let nickName = myData["nickName"] as? String ?? ""
        }
        if (diff.type == .modified) {
            let nickName = myData["nickName"] as? String ?? ""
        }
        if (diff.type == .removed) {
            let nickName = myData["nickName"] as? String ?? ""
        }
    }
}

Solution

  • Unfortunately, that is not a feature of Firestore. What you can do is have another field oldNickName and using Firebase Functions, automatically update that when the nickName field is changed.

    The best solution is storing nickName locally, so you can refer back to your local variable when nickName changes, accessing the newly updated one in the database and the previous nickName locally. Here is the updated code:

    var nickNames = [String : String]()
    db.collection("cities").whereField("state", isEqualTo: "CA").addSnapshotListener { snapshot, error in
        guard error == nil, let snapshot = snapshot?.documentChanges else { return }
        snapshot.forEach {
            let document = $0.document
            let documentID = document.documentID
            let nickName = document.get("nickName") as? String ?? "Error"
            switch $0.type {
                case .added:
                    print("New city: \(document.data())")
                    nickNames[documentID] = nickName
                case .modified:
                    print("Nickname changed from \(nickNames[documentID]) to \(nickName)")
                    nickNames[documentID] = nickName
                case .removed:
                    print("City removed with nickname \(nickNames[documentID])")
                    nickNames.removeValue(forKey: documentID)
            }
        }
    }
    

    nickNames is a dictionary with key cityID and value nickName. This code is written in Swift 5.