2017-09-25 81 views
0

我试图在使用Firebase的社交媒体应用中处理以下并取消追踪。我有一个名为“Follow”的酒吧按钮项目。点击时,它会检查当前的跟踪状态(在viewDidLoad中检索),并相应地调用跟随/取消关注方法。 user代表页面的所有者,以及currentUser想要关注/取消关注的人员。Firebase更新孩子的价值观正在消除子女

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

这是我的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

有不少会在这里解压,但我尽我所能跟着,并拿出一个解决方案。其一,而不是有两个功能,创建处理以下和取消关注单一的功能:

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

在此功能,听一次,你需要的是儿童的价值。而不是使用childByAutoId,请使用uid作为键,任何值都可以。我只用了true。这意味着您可以直接观察参考,而不必遍历所有寻找一个追随者的孩子。如果孩子的数据是零,那么用户还没有关注,所以数据库被更新以遵循。如果孩子的数据不是零,数据将被删除。

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() 
     } 
    }) 
} 

现在可能有一些语法错误,因为我在做这个盲目的,但这是什么,我会建议的要点。您可能需要调整以满足您的需求。

+0

我不得不做出一些改变来得到这个工作,但它仍然不是我预想的事情。正如您目前编写的那样,创建引用时,您在字符串插值期间添加了一些感叹号。我还必须将if snapshot.value == nil检查更改为if!snapshot.exists(),因为nil与Any的比较失败。 –

+0

另一件事是JSON树看起来不像预期的那样。它现在变成users/currentUser.uid/following/user.uid /(user.uid:true)。我希望能在没有重复孩子的情况下构建它。即users/currentUser.uid/following /(user.uid:true)。当我尝试这个时,每个新用户都会覆盖最后一个。我希望这是有道理的。我怎样才能得到想要的结果?或者我应该保持原样? –

0

我会选择Jen的答案作为正确答案,但我想添加我的工作代码。我不得不做一些改变来实现我的愿景。您无法将snapshot.value与nil进行比较,因此您应该使用if snapshot.exists()。为了避免在参考点使用ref.updateChildValues()添加一个全新的小孩,我使用了.setValue("true")。这只是将一个新的键值对添加到ref的“follow”和“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" 
      } 
     } 
    }) 
} 

这里是我的树的照片: tree picture