如何检查特定值(UID)的firebase子节点?

时间:2017-04-19 18:43:06

标签: ios swift firebase firebase-realtime-database

我正在尝试查询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 个答案:

答案 0 :(得分: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对此进行扩展,以跟踪此用户所属的房间中发生的任何事件。因此,如果另一个用户加入或离开该用户所在的房间,将通知app;如果房间的主人从房间引导此用户,则还会通知应用程序。

答案 1 :(得分:-1)

理想情况下,您可以在应用中创建一个单独的节点来存储所需的信息。类似的东西:

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

这将允许您获取用户的节点,并立即查看他们分开的房间。完成后,您可以循环结果以获得各个房间。在保持此列表更新方面,请查看firebase函数或滚动自己的列表。