Firebase 更新 child 值正在删除 children
Firebase update child values is removing children
我正在尝试使用 Firebase 在我的社交媒体应用程序中处理关注和取消关注。我有一个标题为 "Follow" 的栏按钮项。点击时,它会检查当前的关注状态(在 viewDidLoad 中检索),并相应地调用 follow/unfollow 方法。 user
代表页面的所有者,currentUser
想要 follow/unfollow.
的人
意外行为:第二次关注用户时,您可以看到数据库中正确的 child 节点出现,然后消失。他们不应该消失。我已经刷新页面以确保节点实际上以某种方式被删除。它在每次应用程序启动后的第一次尝试中都能正常工作。
这是我的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"
}
}
}
}
这是点击 Follow/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 树的照片:
这里有很多事情要解压缩,但我尽力跟进并提出了解决方案。首先,创建一个处理关注和取消关注的函数,而不是拥有两个函数:
@IBAction func followUserButtonPressed(_ sender: Any) {
followOrUnfollow()
}
在该函数中,听一次您需要的 child 的值。不要使用 childByAutoId
,而是使用 uid
作为键,使用任何东西作为值。我刚刚使用了 true
。这意味着您可以直接观察引用,而不必遍历所有 children 来寻找一个关注者。如果 child 的数据为 nil,那么用户还没有关注,因此更新数据库以关注。如果child的数据不为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()
}
})
}
现在可能会有一些语法错误,因为我正在盲目地研究这个,但这是我推荐的要点。您可能需要对此进行调整以满足您的需求。
我会 select Jen 的回答是正确的,但我想添加我的工作代码。我不得不做出一些改变来实现我的愿景。您不能将 snapshot.value 与 nil 进行比较,因此您应该使用 if snapshot.exists()
。为了避免使用ref.updateChildValues()
在参考点添加一个全新的child,我使用了.setValue("true")
。这只是将新的 key-value 对添加到 ref 的 "following" 和 "followers" 节点。
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"
}
}
})
}
我正在尝试使用 Firebase 在我的社交媒体应用程序中处理关注和取消关注。我有一个标题为 "Follow" 的栏按钮项。点击时,它会检查当前的关注状态(在 viewDidLoad 中检索),并相应地调用 follow/unfollow 方法。 user
代表页面的所有者,currentUser
想要 follow/unfollow.
意外行为:第二次关注用户时,您可以看到数据库中正确的 child 节点出现,然后消失。他们不应该消失。我已经刷新页面以确保节点实际上以某种方式被删除。它在每次应用程序启动后的第一次尝试中都能正常工作。
这是我的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"
}
}
}
}
这是点击 Follow/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 树的照片:
这里有很多事情要解压缩,但我尽力跟进并提出了解决方案。首先,创建一个处理关注和取消关注的函数,而不是拥有两个函数:
@IBAction func followUserButtonPressed(_ sender: Any) {
followOrUnfollow()
}
在该函数中,听一次您需要的 child 的值。不要使用 childByAutoId
,而是使用 uid
作为键,使用任何东西作为值。我刚刚使用了 true
。这意味着您可以直接观察引用,而不必遍历所有 children 来寻找一个关注者。如果 child 的数据为 nil,那么用户还没有关注,因此更新数据库以关注。如果child的数据不为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()
}
})
}
现在可能会有一些语法错误,因为我正在盲目地研究这个,但这是我推荐的要点。您可能需要对此进行调整以满足您的需求。
我会 select Jen 的回答是正确的,但我想添加我的工作代码。我不得不做出一些改变来实现我的愿景。您不能将 snapshot.value 与 nil 进行比较,因此您应该使用 if snapshot.exists()
。为了避免使用ref.updateChildValues()
在参考点添加一个全新的child,我使用了.setValue("true")
。这只是将新的 key-value 对添加到 ref 的 "following" 和 "followers" 节点。
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"
}
}
})
}