Firebase更新子级值正在删除子级

时间:2017-09-25 20:41:24

标签: ios json swift firebase uibarbuttonitem

我正在尝试使用Firebase在我的社交媒体应用中处理以下内容并取消关注。我有一个标题为“关注”的栏按钮项目。点击时,它会检查当前的跟随状态(在viewDidLoad中检索),并相应地调用follow / unfollow方法。 user代表网页的所有者,以及currentUser想要关注/取消关注的人。

意外行为:当第二次关注用户时,您可以看到数据库中正确的子节点出现,然后消失。他们不应该消失。我刷新了页面,以确保节点实际上被删除。每次应用启动后,它都会在第一次尝试时正常工作。

这是我的viewDidLoad(负责检索currentUserIsFollowing)。我怀疑问题出在这里:

override func viewDidLoad() {
    super.viewDidLoad()

    let userDogRef = Database.database().reference().child("users").child(user.uid!).child("dogs")

    let followingRef = Database.database().reference().child("users").child((Auth.auth().currentUser?.uid)!).child("following")

    followingRef.observeSingleEvent(of: .childAdded) { (snapshot) in
        if snapshot.value == nil {
            print("no following found")
            return
        }
        let value = snapshot.value as? NSDictionary
        let followingUserUID = String(describing: value!["uid"]!)
        if self.user.uid == followingUserUID {
            self.currentUserIsFollowing = true
            DispatchQueue.main.async {
                self.followBarButtonItem.title = "Unfollow"
            }
        }

    }
}

以下是点按“关注/取消关注”按钮时调用的操作:

@IBAction func followUserButtonPressed(_ sender: Any) {
    if !currentUserIsFollowing {
        followUser()
        return
    }
    if currentUserIsFollowing {
        unfollowUser()
        return
    }
}

以下是followUser()方法:

fileprivate func followUser() {
    let followingRef = Database.database().reference().child("users").child((Auth.auth().currentUser?.uid)!).child("following")
    let followersRef = Database.database().reference().child("users").child(user.uid!).child("followers")

    followingRef.childByAutoId().updateChildValues(["uid": user.uid as Any]) { (error, ref) in
        if error != nil {
            print(String(describing: error?.localizedDescription))
        }
    }

    followersRef.childByAutoId().updateChildValues(["uid": Auth.auth().currentUser?.uid as Any]) { (error, ref) in
        if error != nil {
            print(String(describing: error?.localizedDescription))
        }
    }

}

以下是unfollowUser()方法:

fileprivate func unfollowUser() {
    let followingRef = Database.database().reference().child("users").child((Auth.auth().currentUser?.uid)!).child("following")
    let followersRef = Database.database().reference().child("users").child(user.uid!).child("followers")

    followingRef.observeSingleEvent(of: .childAdded, with: { (snapshot) in
        if snapshot.value == nil {
            print("no following found")
        }
        let value = snapshot.value as? NSDictionary
        let followingUserUID = String(describing: value!["uid"]!)
        if self.user.uid == followingUserUID {
            snapshot.ref.removeValue()
        }
    })

    followersRef.observeSingleEvent(of: .childAdded, with: { (snapshot) in
        if snapshot.value == nil {
            print("no followers found")
        }
        let value = snapshot.value as? NSDictionary
        let followerUserUID = String(describing: value!["uid"]!)
        if Auth.auth().currentUser?.uid == followerUserUID {
            snapshot.ref.removeValue()
        }
    })

}

这是我的JSON树的照片:

a photo of my JSON tree

2 个答案:

答案 0 :(得分:2)

这里有很多东西需要解压,但我尽力跟进并提出解决方案。例如,创建一个处理跟随和取消跟随的函数,而不是具有两个函数:

@IBAction func followUserButtonPressed(_ sender: Any) {
    followOrUnfollow()
}

在该功能中,只需听一次您需要的孩子的价值。不使用childByAutoId,而是使用uid作为键,使用任何值作为值。我刚刚使用了true。这意味着您可以直接观察参考,而不必遍历寻找一个追随者的所有孩子。如果孩子的数据为零,则用户尚未关注,因此数据库将更新以跟随。如果孩子的数据不是nil,则删除数据。

func followOrUnfollow() {
    let followingRef = Database.database().reference().child("users/\(Auth.auth().currentUser?.uid)!/following/\(user.uid!)")
    let followersRef = Database.database().reference().child("users/\(user.uid)!/followers/\(Auth.auth().currentUser?.uid)!")

    followingRef.observeSingleEvent(of: .value, with: { (snapshot) in
         if snapshot.value == nil {
            print("no following found")
            followingRef.updateChildValues([user.uid: "true"]) { (error, ref) in
                if error != nil {
                    print(String(describing: error?.localizedDescription))
                }
            }
        } else {
            print("unfollowing")
            snapshot.ref.removeValue()
        }
    })

    followersRef.observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.value == nil {
            print("no followers found")
            followersRef.updateChildValues([Auth.auth().currentUser?.uid: "true"]) { (error, ref) in
                if error != nil {
                    print(String(describing: error?.localizedDescription))
                }
            }
        } else {
            print("unfollowing")
            snapshot.ref.removeValue()
        }
    })
}

现在可能会出现一些语法错误,因为我正在盲目地处理这个问题,但这是我推荐的要点。您可能需要调整它以满足您的需求。

答案 1 :(得分:0)

我会选择Jen的答案作为正确答案,但我想添加我的工作代码。我不得不做出一些改变来实现我的愿景。您无法将snapshot.value与nil进行比较,因此您应该使用if snapshot.exists()。为了避免使用ref.updateChildValues()在参考点添加全新的孩子,我使用了.setValue("true")。这只是为"跟随"添加了一个新的键值对。和"粉丝"参考的节点。

func followOrUnfollow() {

    let followingRef = Database.database().reference().child("users/\(Auth.auth().currentUser!.uid)/following/\(self.user.uid!)")
    let followersRef = Database.database().reference().child("users/\(user.uid!)/followers/\(Auth.auth().currentUser!.uid)")

    followingRef.observeSingleEvent(of: .value, with: { (snapshot) in
        if !snapshot.exists() {
            print("no following found")
            followingRef.setValue("true") { (error, ref) in
                if error != nil {
                    print(String(describing: error?.localizedDescription))
                }

            }
        } else {
            print("unfollowing")
            snapshot.ref.removeValue()
        }
    })

    followersRef.observeSingleEvent(of: .value, with: { (snapshot) in
        if !snapshot.exists() {
            print("no followers found")
            followersRef.setValue("true") { (error, ref) in
                if error != nil {
                    print(String(describing: error?.localizedDescription))
                }
                DispatchQueue.main.async {
                    self.followBarButtonItem.title = "Unfollow"
                }
            }
        } else {
            print("unfollowing")
            snapshot.ref.removeValue()
            DispatchQueue.main.async {
                self.followBarButtonItem.title = "Follow"
            }
        }
    })
}

这是我的树的照片: tree picture