2017-09-25 1 views
0

J'essaie de gérer et de ne pas suivre dans mon application de médias sociaux en utilisant Firebase. J'ai un bouton intitulé "Suivre". Lorsqu'il est appuyé, il vérifie l'état de suivi actuel (récupéré dans viewDidLoad) et appelle les méthodes follow/unfollow en conséquence. user représente le propriétaire de la page, et la personne que le currentUser veut suivre/ne plus suivre. Comportement inattendu: Lorsque vous suivez un utilisateur une seconde fois, vous pouvez voir apparaître les noeuds enfants appropriés dans la base de données, puis disparaître. Ils ne devraient pas disparaître. J'ai rafraîchi la page pour m'assurer que les nœuds sont effectivement supprimés d'une manière ou d'une autre. Cela fonctionne correctement sur le premier essai après chaque lancement d'application.Les valeurs enfant Firebase mise à jour est la suppression des enfants

Voici mon viewDidLoad (chargé de récupérer currentUserIsFollowing). Je soupçonne que la question est ici:

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

    } 
} 

est ici l'action appelée lorsque le bouton Suivre/Arrêter de suivre est taraudée:

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

Voici la méthode 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)) 
     } 
    } 

} 

Voici la méthode 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() 
     } 
    }) 

} 

Voici une photo de mon arbre JSON:

a photo of my JSON tree

Répondre

2

Il est tout à fait un peu passe ici pour déballer, mais j'ai essayé de mon mieux pour suivre et trouver une solution. D'une part, au lieu d'avoir deux fonctions, créer une seule fonction qui gère et suit désabonnement:

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

Dans cette fonction, écouter une fois la valeur de l'enfant dont vous avez besoin. Au lieu d'utiliser childByAutoId, utilisez le uid comme clé et n'importe quoi comme valeur. Je viens d'utiliser true. Cela signifie que vous pouvez observer directement la référence au lieu d'avoir à parcourir tous les enfants à la recherche du disciple. Si les données de l'enfant sont nulles, l'utilisateur ne suit pas encore, donc la base de données est mise à jour pour suivre. Si les données de l'enfant ne sont pas nulles, les données sont supprimées.

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

Maintenant, il peut y avoir des erreurs syntaxiques parce que je travaille sur ce aveuglément, mais cela est l'essentiel de ce que je recommande. Vous devrez probablement ajuster cela pour répondre à vos besoins.

+0

je devais faire quelques changements pour obtenir ce travail, mais il est toujours pas comment j'envisageais les choses.Comme vous l'avez déjà écrit, vous ajoutez quelques points d'exclamation lors de l'interpolation de votre chaîne lors de la création de références. J'ai aussi dû changer if snapshot.value == nil vérifie si! Snapshot.exists() parce que la comparaison de nil à Any échouait. –

+0

Une autre chose est que l'arborescence JSON ne ressemble pas comme prévu. Il va maintenant users/currentUser.uid/following/user.uid/(user.uid: true). J'espérais le structurer sans l'enfant dupliqué. c'est-à-dire users/currentUser.uid/following/(user.uid: true). Lorsque j'essayais cela, chaque nouvel utilisateur suivi écrasait le dernier. J'espère que cela à du sens. Comment puis-je obtenir le résultat souhaité? Ou devrais-je simplement laisser tel quel? –

0

Je choisirai la réponse de Jen comme la bonne, mais je veux ajouter mon code de travail. J'ai dû faire quelques changements pour mettre en œuvre ma vision. Vous ne pouvez pas comparer un snapshot.value à nil, vous devriez donc utiliser if snapshot.exists(). Afin d'éviter d'ajouter un nouvel enfant au point de référence en utilisant ref.updateChildValues(), j'ai utilisé .setValue("true"). Cela ajoute simplement une nouvelle paire clé-valeur aux nœuds "following" et "followers" à la ref.

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

Voici une photo de mon arbre: tree picture