Reputation: 1301
I'm trying to query Firebase to check if the current user's uid is listed in a room's "participants". If so, I grab the info for that room.
Below is my current observer which listens to ALL rooms in the app, not just the rooms the user is a participant of. But I need to perform a check first, to see which rooms the current user's UID is listed in; if there's a match (the uid is in a room's participants), THEN get the data for that room:
private func observeRooms() {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {print("Error getting user UID"); return}
roomRefHandle = roomRef.observe(.childAdded, with: { (snapshot) -> Void in
let roomData = snapshot.value as! Dictionary<String, AnyObject>
let id = snapshot.key
guard let name = roomData["roomName"] as! String! else {print("Error getting user name"); return}
self.usersRooms.append(Room(id: id, name: name, participants: [uid]))
self.tableView.reloadData()
})
}
This is how the rooms are structured in the database:
"rooms" : {
"-Ki6TJWO-2R1L4SyhSqn" : {
"messages" : {
"-Ki6TWrXxWqjaRJAbyVt" : {
"senderId" : "tzfHgGKWLEPzPU9GvkO4XE1QKy53",
"senderName" : "Timothy",
"text" : "Room One message"
}
},
"participants" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : true
},
"roomName" : "Room One"
},
"-Ki6TKOnmToeUuBzrnbb" : {
"participants" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : true
},
"roomName" : "Room Two"
},
"-Ki6TLGC1Encm1v-CbHB" : {
"participants" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : true
},
"roomName" : "Room Three"
}
}
How can I change my function so that it first checks all the room's participants for the current user's uid, before grabbing the values?
Thanks for any suggestions!
EDIT: Jay's approach:
private func observeRooms() {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {print("Error getting user UID"); return}
let queryRef = roomRef.queryOrdered(byChild: "participants/\(uid)").queryEqual(toValue: true)
queryRef.observe(.childAdded, with: { snapshot in
let roomDict = snapshot.value as! [String: AnyObject]
let id = snapshot.key
let roomName = roomDict["roomName"] as! String
let participants = roomDict["participants"] as! [String: AnyObject]
let numberOfParticipants = participants.count
print("\nRoom Name: \(roomName)")
print("Participants: \(participants)")
print("Room ID: \(id)\n")
self.usersRooms.append(Room(id: id, name: roomName, participants: [uid]))
self.tableView.reloadData()
})
}
Upvotes: 1
Views: 488
Reputation: 35657
To keep it super simple, store a reference to the user in each room they belong to.
rooms
room_0
room_name: "My Room"
users
user_1: true
user_2: true
room_1
room_name: "Their Room"
users
user_1: true
Then a simple query which will gather all the needed data, and will also leave an observer attached so if this user joins any new rooms the app will be notified.
let roomsUsersRef = self.ref.child("rooms")
let queryRef = roomsUsersRef.queryOrdered(byChild: "users/user_1").queryEqual(toValue: true)
queryRef.observe(.childAdded, with: { snapshot in
let roomDict = snapshot.value as! [String: AnyObject]
let roomName = roomDict["room_name"] as! String
let usersDict = roomDict["users"] as! [String: AnyObject]
let userCount = usersDict.count
print("Room: \(roomName) has \(userCount) users")
})
and the output
Room: My Room has 2 users
Room: Their Room has 1 users
You could expand on this with .childChanged and .childRemoved to keep track of any events that occur in a room this user belongs to. So if another user joins or leaves a room this user is in, app will be notified; if the owner of the room boots this user from the room, the app will also be notified.
Upvotes: 2
Reputation: 28750
Ideally you would create a separate node in your app to store the information you want. Something like:
{
"usersRooms": {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53": {
"-Ki6TJWO-2R1L4SyhSqn": true,
"-Ki6TKOnmToeUuBzrnbb": true,
"-Ki6TLGC1Encm1v-CbHB": true
}
}
}
This would allow you to get the node for the user and instantly see what rooms they are apart of. Once you've done that you can loop over the results to get the individual rooms. In terms of keeping this list updated look into firebase functions or roll your own.
Upvotes: -1