Ios Firebase更新子值正在删除子项
我正在尝试使用Firebase在我的社交媒体应用程序中处理跟踪和取消跟踪。我有一个标题为“跟随”的酒吧按钮项目。点击时,它检查当前的跟随状态(在viewDidLoad中检索),并相应地调用跟随/取消跟随方法Ios Firebase更新子值正在删除子项,ios,json,swift,firebase,uibarbuttonitem,Ios,Json,Swift,Firebase,Uibarbuttonitem,我正在尝试使用Firebase在我的社交媒体应用程序中处理跟踪和取消跟踪。我有一个标题为“跟随”的酒吧按钮项目。点击时,它检查当前的跟随状态(在viewDidLoad中检索),并相应地调用跟随/取消跟随方法user表示页面的所有者,以及currentUser希望跟踪/取消跟踪的人 意外行为:第二次跟踪用户时,可以看到数据库中正确的子节点出现,然后消失。它们不应该消失。我刷新了页面,以确保节点实际上以某种方式被删除。它在每次应用程序启动后的第一次尝试中都能正常工作 这是我的viewDidLoad(
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))
}
}
}
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()
}
})
}
以下是unfollowUser()
方法:
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))
}
}
}
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()
}
在这个函数中,听一次你需要的孩子的价值观。不要使用childByAutoId
,而是使用uid
作为键,使用任何内容作为值。我刚刚用了true
。这意味着您可以直接观察引用,而不必遍历所有子对象来寻找一个跟随者。如果子对象的数据为nil,则用户尚未跟踪,因此数据库将更新为跟踪。如果子项的数据不是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()
}
})
}
现在可能会有一些语法错误,因为我是盲目的,但这是我建议的要点。您可能需要对此进行调整以满足您的需要。我将选择Jen的答案作为正确答案,但我想添加我的工作代码。我必须做出一些改变来实现我的愿景。无法将snapshot.value与nil进行比较,因此如果snapshot.exists(),则应使用
。为了避免使用ref.updateChildValues()
在参考点添加一个全新的子项,我使用了.setValue(“true”)
。这只是将一个新的键值对添加到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"
}
}
})
}
这是我的树的照片:
我必须做出一些改变才能让它正常工作,但这仍然不是我想象的那样。正如您目前所写的,在创建引用时,在字符串插值过程中添加了几个感叹号。我还必须将if snapshot.value==nil检查更改为if!snapshot.exists()是因为将nil与Any进行比较失败。另一个原因是JSON树的外观与预期不符。现在转到users/currentUser.uid/following/user.uid/(user.uid:true)。我希望在没有复制孩子的情况下构建它。i、 e.users/currentUser.uid/following/(user.uid:true)。当我尝试这样做时,每个新用户都会覆盖上一个用户。我希望这是有道理的。我怎样才能得到想要的结果?还是我应该保持原样?