我正在开发群聊应用程序,但我在尝试向Firebase数据库发出特定查询时遇到了麻烦。
我需要获取一个房间内用户的所有个人资料照片。但只有当前用户所属的房间。
private func observeRooms() {
let databaseRef = FIRDatabase.database().reference()
let groupRef = databaseRef.child("groups")
guard let uid = FIRAuth.auth()?.currentUser?.uid else {return}
let queryRef = groupRef.queryOrdered(byChild: "participants/\(uid)").queryEqual(toValue: nil)
queryRef.observe(.childAdded, with: { snapshot in
let roomDict = snapshot.value as! [String: AnyObject]
print("roomDict: \(roomDict)")
let id = snapshot.key
let avatar = roomDict["profilePicture"] as! String
})
}
显然,设置queryEqual(toValue: nil)
会返回当前用户不属于的所有房间 - 与我需要的相反。我知道反过来会检查queryEqual(toValue: true)
,但: true
没有显示在数据库中。
这就是我将节点添加到" groups"在Firebase中:
// Start group node for new room
let groupRef: FIRDatabaseReference = FIRDatabase.database().reference().child("groups")
let roomID = newRoomRef.key
let groupRoomRef = groupRef.child(roomID)
let groupDict = ["roomName" : roomName, "participants": [uid : true]] as [String : Any]
groupRoomRef.setValue(groupDict)
这就是数据结构的结束方式:
"groups" : {
"-KkGzZ7frbnXmImt0JpV" : {
"participants" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : {
"gender" : "male",
"handle" : "Testing",
"name" : "Test User",
"profilePicture" : "https://graph.facebook.com/*removed*/picture?type=large&return_ssl_resources=1",
"status" : "F8B016"
}
},
"roomName" : "Test Room"
},
如何才能正确处理会议室中所有用户的profilePicture
值,仅适用于当前用户的UID所参与的群组?
答案 0 :(得分:1)
你走在正确的轨道上。使用queryEqual
时,您的查询需要匹配数据库中实际存在的值。不幸的是,当您要查询的值是复杂对象时会变得复杂。事实上,即使您确实匹配了整个对象值,我也不确定该功能是否可行。这里的问题是您尝试通过子键的存在来查找对象,而不是实际排序或匹配其值。这并不适合任何orderBy
方法的用例。
有几种方法可以解决这个问题,需要努力。
首先,您可以利用sort order只获得那些拥有某个对象且具有UID名称的人。由于Firebase首先排序空,然后是基元,最后是对象,您应该能够按子顺序排序,从 true
(或任何基元)开始,以获取具有该键的所有对象实例(当然,假设您没有将UID: true
存储在任何地方。
groupRef.queryOrdered(byChild: "participants/\(uid)").queryStartingAtValue(true)
第二次,将UID复制为对象内的值true
,以便您可以直接对其进行排序。注意查询中的额外步骤。
"groups" : {
"-KkGzZ7frbnXmImt0JpV" : {
"participants" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : true,
...
groupRef.queryOrdered(byChild: "participants/\(uid)/\(uid)").queryEqual(toValue: true)
最后,这就是我的建议,重新考虑您的数据结构。您在此集合集合中嵌入了大量数据,这些数据将使您的查询和更新变得难以处理。当你denormalize your data时,Firebase往往会更好地工作,更喜欢平面/浅层结构,并且有一些简单数据的重复。在您的情况下,您可能拥有一组组和另一组用户,而不是将用户的配置文件数据存储在其组成员中,而每个组只包含其成员的true
的值,以便您可以再次使用简单的值查询。
"groups" : {
"-KkGzZ7frbnXmImt0JpV" : {
"participants" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : true
...
"users" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : {
"groups" : {
"-KkGzZ7frbnXmImt0JpV" : true
...
groupRef.queryOrdered(byChild: "participants/\(uid)").queryEqual(toValue: true)