How to loop through AutoIdChilds in Firebase?

I have this social app like twitter and when the user looks for another user I want to see if the logged in user follows the other user, but i don't know how to loop through and find out if the logged in user already follows the other one.

{
  "follower" : {
    "mt0fzirhMhazIcy90MRWuRpTfmE2" : {
      "-KbHXdeiOfGXzvavuQ_5" : {
        "uid" : "dEXaVLDOSPfJa3zTyUNqAEtVuMR2"
      }
    }
  },
  "following" : {
    "dEXaVLDOSPfJa3zTyUNqAEtVuMR2" : {
      "-KbHXdehbkeMvDyzNpRE" : {
        "uid" : "mt0fzirhMhazIcy90MRWuRpTfmE2"
      }
    }
  },
  "handles" : {
    "jcadmin" : "mt0fzirhMhazIcy90MRWuRpTfmE2",
    "jcbest" : "dEXaVLDOSPfJa3zTyUNqAEtVuMR2"
  },
  "user_profiles" : {
    "dEXaVLDOSPfJa3zTyUNqAEtVuMR2" : {
      "about" : "Hello world",
      "handle" : "jcbest",
      "name" : "Juan Carlos Estevez Rodriguez",
      "profile_pic" : "https://firebasestorage.googleapis.com/v0/b..."
    },
    "mt0fzirhMhazIcy90MRWuRpTfmE2" : {
      "about" : "Hello",
      "handle" : "jcadmin",
      "name" : "Juan Carlos",
      "profile_pic" : "https://firebasestorage.googleapis.com/v0..."
    }
  }
}

This is my Database, what i want will be something like this

   self.databaseRef.child("following").child((self.loggedInUser?.uid)!).observe(.value, with: { (snapshot) in
        let snapshot = snapshot.value as? [String: AnyObject]

        if("The other user UID exists in the following")
        {
            self.followButton.tittleLabel = "Unfollow"
        }

    })

Upvotes: 0

Views: 577

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 599021

Using Firebase's push()/childByAutoId() method is great for getting a collection that it guaranteed to have unique children and that is ordered chronologically, somewhat like an array in most other languages.

But your collection of users is of a different type: it is more like a set. In a set, each value can occur only once. In the Firebase Database you'd model a set like this:

{
  "follower" : {
    "mt0fzirhMhazIcy90MRWuRpTfmE2" : {
        "dEXaVLDOSPfJa3zTyUNqAEtVuMR2": true
    }
  },
  "following" : {
    "dEXaVLDOSPfJa3zTyUNqAEtVuMR2" : {
        "mt0fzirhMhazIcy90MRWuRpTfmE2": true
    }
  },
  ...

So this puts the UID as they key, guaranteeing that each follower can only be present once in the collection (since keys must be unique in their context). The value true is just there since the database cannot store a key without a value, it has no meaning.

Now you can access the users "followings" with:

self.databaseRef
    .child("following")
    .child((self.loggedInUser?.uid)!)
    .observe(.value, with: { (snapshot) in
        for child in snapshot.children {
            print("Following \((child.key!))"
        }
    })

Upvotes: 1

Callam
Callam

Reputation: 11539

You don't need an $autoId, you can just use the follower/following user's $uid as the key.

"follower" : {
  "mt0fzirhMhazIcy90MRWuRpTfmE2" : {
    "dEXaVLDOSPfJa3zTyUNqAEtVuMR2": true
  }
},
"following" : {
  "dEXaVLDOSPfJa3zTyUNqAEtVuMR2" : {
    "mt0fzirhMhazIcy90MRWuRpTfmE2": true
  }
},

Then you can observe the value of /following/$uid/$userId, switch the snapshot value to determine whether it's a Bool equal to true or just null.

let uid = FIRAuth.auth()!.currentUser!.uid
let ref = FIRDatabase.database().reference(
    withPath: "following/\(uid)/$userId"
)

ref.observe(.value, with: { (snapshot) in
    switch snapshot.value {
    case let value as Bool where value:
        // value was a Bool and equal to true
        self.followButton.tittleLabel = "Unfollow"
    default:
        // value was either null, false or could not be cast
        self.followButton.tittleLabel = "Follow"
    }
})

Upvotes: 1

Related Questions