2017-09-25 6 views
0

Ich versuche, mit Firebase in meiner Social Media App zu folgen und nicht zu folgen. Ich habe eine Bar-Taste mit dem Titel "Follow". Wenn er angetippt wird, prüft er den aktuellen Folgestatus (abgerufen in viewDidLoad) und ruft entsprechend die follow/unfollow-Methoden auf. user repräsentiert den Besitzer der Seite, und die Person die currentUser will folgen/nicht folgen.Firebase update child values ​​entfernt Kinder

Unerwartetes Verhalten: Wenn Sie einem Benutzer ein zweites Mal folgen, können Sie beobachten, wie die richtigen untergeordneten Knoten in der Datenbank angezeigt werden und dann ausgeblendet werden. Sie sollten nicht verschwinden. Ich habe die Seite aktualisiert, um sicherzustellen, dass die Knoten tatsächlich tatsächlich gelöscht werden. Es funktioniert beim ersten Versuch nach jedem Start der App ordnungsgemäß.

Hier ist meine ViewDidLoad (verantwortlich für das Abrufen von currentUserIsFollowing). Ich vermute, das Problem liegt hier:

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" 
      } 
     } 

    } 
} 

Hier die Aktion aufgerufen, wenn die Folgen/Unfollow Taste abgegriffen wird:

@IBAction func followUserButtonPressed(_ sender: Any) { 
    if !currentUserIsFollowing { 
     followUser() 
     return 
    } 
    if currentUserIsFollowing { 
     unfollowUser() 
     return 
    } 
} 

Hier ist die followUser() Methode:

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

} 

Hier die unfollowUser() methode:

ist hier ein Foto von meinem JSON Baum:

a photo of my JSON tree

Antwort

2

Es ist ziemlich viel los hier auspacken, aber ich versuchte mein Bestes zu folgen und mit einer Lösung kommen. Zum einen, sondern zwei Funktionen haben, erstellen Sie eine einzelne Funktion, die folgenden und Unfollowing Griffe:

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

In dieser Funktion hört einmal auf den Wert des Kindes die Sie benötigen. Verwenden Sie anstelle von childByAutoId die uid als Schlüssel und alles als Wert. Ich habe gerade true verwendet. Dies bedeutet, dass Sie die Referenz direkt beobachten können, anstatt alle Kinder durchlaufen zu müssen, die nach dem einen Follower suchen. Wenn die Daten des Kindes null sind, folgt der Benutzer noch nicht, so dass die Datenbank aktualisiert wird, um zu folgen. Wenn die Daten des Kindes nicht Null sind, werden die Daten entfernt.

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

Jetzt kann es einige syntaktische Fehler sein, weil ich auf diese blind bin zu arbeiten, aber das ist der Kern dessen, was ich empfehlen würde. Sie müssen dies wahrscheinlich anpassen, um Ihre Bedürfnisse zu erfüllen.

+0

musste ich einige Änderungen vornehmen diese Funktion zu erhalten, aber es ist immer noch nicht, wie ich die Dinge in Betracht gezogen.Wie Sie gerade geschrieben haben, fügen Sie während der String-Interpolation beim Erstellen von Referenzen einige Ausrufezeichen hinzu. Ich musste auch das if snapshot.value == nil auf if! Snapshot.exists() überprüfen, da der Vergleich von nil zu Any fehlgeschlagen ist. –

+0

Eine andere Sache ist, dass der JSON-Baum nicht wie erwartet aussieht. Es geht jetzt Benutzer/currentUser.uid/folgende/user.uid/(user.uid: true). Ich hatte gehofft, es ohne das doppelte Kind zu strukturieren. d. h. Benutzer/currentUser.uid/following/(user.uid: true). Wenn ich das versuchte, überschrieb jeder neue Benutzer den letzten. Ich hoffe das ergibt Sinn. Wie kann ich das gewünschte Ergebnis erzielen? Oder sollte ich es einfach so lassen wie es ist? –

0

Ich werde Jens Antwort als die richtige auswählen, aber ich möchte meinen Arbeitscode hinzufügen. Ich musste einige Änderungen vornehmen, um meine Vision umzusetzen. Sie können einen snapshot.value nicht mit nil vergleichen, verwenden Sie stattdessen if snapshot.exists(). Um zu vermeiden, dass ein ganz neues Kind am Referenzpunkt mit ref.updateChildValues() hinzugefügt wird, habe ich .setValue("true") verwendet. Dies fügt nur ein neues Schlüssel/Wert-Paar zu den Knoten "following" und "followers" am ref hinzu.

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

Hier ist ein Bild von meinem Baum: tree picture