2017-04-19 45 views
1

我試圖查詢Firebase以檢查當前用戶的uid是否列在房間的「參與者」中。如果是這樣,我抓住那個房間的信息。如何檢查firebase子節點的特定值(UID)?

下面是我目前的觀察者,它傾聽應用中的所有房間,而不僅僅是用戶參與的房間。但是我需要首先執行檢查,以查看哪些房間當前用戶的UID被列入;如果有一個匹配(UID是在一個房間裏的人),然後獲取數據,那個房間:

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

這是房間如何在數據庫中的結構化:

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

我怎樣才能改變我的功能,以便它首先檢查所有房間的參與者當前用戶的uid,然後獲取值?

感謝您的任何建議!

編輯:周杰倫的做法:

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

回答

2

爲了保持超級簡單,請在用戶所屬的每個房間中存儲對用戶的引用。

rooms 
    room_0 
    room_name: "My Room" 
    users 
    user_1: true 
    user_2: true 
    room_1 
    room_name: "Their Room" 
    users 
    user_1: true 

然後一個簡單的查詢,將收集所有需要的數據,也將離開附着,所以如果這個用戶加入任何新的房間,應用程序將被通知的觀察員。

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

和輸出

Room: My Room has 2 users 
Room: Their Room has 1 users 

你可以擴大這與.childChanged和.childRemoved跟蹤出現在該用戶屬於一個房間內的任何事件。因此,如果有其他用戶加入或離開該用戶所在的房間,應用程序將被通知;如果房間的所有者從該房間引導該用戶,則該應用也將被通知。

+0

無可否認,這是很難測試的,因爲現在我是所有房間的唯一參與者,所有房間都只有我作爲參與者 - 但我的建議工作正常(請參閱我的問題編輯)。我想知道,這是否只會返回我是(當前用戶)參與者的房間?那麼我現在只能從這些房間中獲取數據? – KingTim

+0

在你的例子中,假設你是'user_2' - 這隻會返回'room_0',因爲你不在'room_1'裏? – KingTim

+0

@KingTim你是對的!你的問題是*我試圖查詢Firebase以檢查當前用戶的uid是否列在房間的「參與者」中。如果是這樣,我可以獲取該房間的信息。*我的解決方案完全符合......以及更多!事實上,如果用戶加入額外的房間,它也會通知應用程序;並添加.childChanged和.childRemoved(或.value如果是少量房間),它會通知您任何更改。其他用戶進入房間或​​離開,房間名稱更改...甚至是新帖! – Jay

-1

理想情況下,你會在你的應用程序來存儲你想要的信息創建一個單獨的節點。像這樣:

{ 
    "usersRooms": { 
     "tzfHgGKWLEPzPU9GvkO4XE1QKy53": { 
      "-Ki6TJWO-2R1L4SyhSqn": true, 
      "-Ki6TKOnmToeUuBzrnbb": true, 
      "-Ki6TLGC1Encm1v-CbHB": true 
     } 
    } 
} 

這將允許您獲取用戶的節點,並立即看到他們分開的房間。完成後,您可以循環播放結果以獲取單個房間。在保持這份清單更新的過程中,可以考慮使用Firebase功能或者自行推出。

+0

這實際上是我之前的做法,因此這裏的另一位用戶建議不要這樣做,因爲這意味着我的每個房間都會有兩次在我的數據庫中 - 例如,如果用戶創建一個新房間,它將進入用戶的房間節點,並且也位於應用程序中所有房間的「全局」列表中。 – KingTim

+0

這會導致應用必須讀取該節點,然後遍歷所有子節點,然後讀取每個房間的信息。真的不是非常高效和難以維護。更好的方法是隻查詢用戶所在房間的房間 - 即離開觀察者,如果有其他用戶加入房間,則會通知此用戶。如果房間名稱發生變化,他們將收到通知等。您只需點擊一次Firebase即可獲取所有需要的數據。 – Jay

+0

不知道是誰告訴你@KingTim。以下是一位Firebase開發人員建議創建反向索引的評論:http:// stackoverflow。com/questions/39850117/remove-indexes-that-in-nested-field-when-deletion-an-object/39851107#comment66998223_39851107 –

相關問題