2017-09-25 79 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