问题
I'm trying to pull a list of my friends and my friend's friends using Firebase. Right now, I'm pulling my list of friends and then looping through their friends to pull their user ID. I would like to append it to a single array with the output ["friendID1","friendID2", "friendID3", "friendID4","friendID5"]. My code so far:
Database.database().reference().child("friends").child(myID).observeSingleEvent(of: .value, with: { (snapshot : DataSnapshot) in
for child in snapshot.children.allObjects as! [DataSnapshot] {
let value = child.value as? NSDictionary
let userId = value?["userId"] as? String ?? ""
Database.database().reference().child("friends").child(friendID1).observeSingleEvent(of: .value, with: { (snapshot : DataSnapshot) in
for child1 in snapshot.children.allObjects as! [DataSnapshot] {
let value1 = child1.value as? NSDictionary
let userId1 = value1?["userId"] as? String ?? ""
self.friendArray.append(userId1)
}
})
}
})
Firebase structure
{
"friends" : {
“currentUserId” : {
“friendId1” : {
“Confirmed” : "yes"
},
“friendId3” : {
“Confirmed” : “Yes”,
}
“friendId5” : {
“Confirmed” : “Yes”,
}
},
“friendId1” : {
“CurrentUserId” : {
“Confirmed” : "yes"
},
“friendId2” : {
“Confirmed” : “Yes”,
}
},
“friendId3” : {
“CurrentUserId” : {
“Confirmed” : "yes"
},
“friendId4” : {
“Confirmed” : “Yes”,
}
},
}
回答1:
The structure you're using is going to cause issues. I would change it to this simple structure:
users
user_0
friends
user_1: true
user_1
friends
user_0: true
user_2: true
user_2
friends
user_1: true
user_3: true
user_3
friends
user_2: true
Then do a query on all of the user nodes that contain my user id.
Assume I am user_0 and want to know my friends, friends
So in this case, my friend is user_1, and user_1's friends are user_0 (me) and user_2. The result should be user_2
Here's the code.
let usersRef = self.ref.child("users")
let queryRef = usersRef.queryOrdered(byChild: "friends/user_0")
.queryEqual(toValue: true)
queryRef.observeSingleEvent(of: .value, with: { snapshot in
var friendsSet = Set<String>()
for child in snapshot.children {
let snap = child as! DataSnapshot
let friendsSnap = snap.childSnapshot(forPath: "friends")
for friendChild in friendsSnap.children {
let friendSnap = friendChild as! DataSnapshot
let uid = friendSnap.key
friendsSet.insert(uid)
}
}
if let index = friendsSet.index(of: "user_0") {
friendsSet.remove(at: index)
}
for uid in friendsSet {
print(uid)
}
})
and the result is
user_2
likewise, if I am user_2 and want to know my friends, friends I would want to know user_1's friends and user_3'friends
and the result is
user_0
This is a simple example, but if user_0 had friends user_1 and user_2 and they had multiple friends, the output would be all of their friends.
Oh - in case you want them sorted...
let sortedFrieds = friendsSet.sorted()
Discussion:
The real magic that makes this work is a Firebase Deep Query - that allows us to drill down one level below the child nodes we are querying. In this case we are querying for all user_x/friends/user_0 equals true.
That snapshot will contain all users that have my (user_0) as a child node. I can then iterate over those users friends nodes and add each key, which is the user id, to a Set.
The Set it being used instead of an Array as we only want unique values stored and for the moment don't care about ordering.
We then toss out my user id (user_0) and the print the result.
来源:https://stackoverflow.com/questions/47645729/querying-friend-of-friends-with-swift