我正在尝试使用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树的照片:
答案 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"
}
}
})
}