Это очень длинный ответ, как ваш вопрос был на самом деле около 5 различных вопросов.
корневой узел: myparentnodename
Ваши пользователи
users
uid_0
name: "William"
door_keys:
key_0: true
key_3: true
uid_2
name: "Leonard"
door_keys:
key_3: true
key_5: true
и ключи
keys
key_0
uid_0: true
key_3
uid_0: true
uid_2: true
key_5
uid_5: true
С этой структурой, все элементы 'точки' друг на друга.
При запросе uid_0 вы можете увидеть, что они используют клавиши 0 и 3
При запросе Key_3 вы можете видеть, что они принадлежат пользователям 0 и 2
Ваш вопрос
каждый время я бы запросил у дочернего узла «пользователи», я бы получил все пользователей назад
Это немного неполное , Когда запрос выполняется, вы обычно запрашиваете что-то конкретное. Однако с Firebase есть два способа извлечения данных: наблюдение за узлом и запрос.
Если вы хотите вернуть всех пользователей в узел пользователя, вы увидите этот узел по .Value (или .ChildAdded по одному за раз).
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath("users")
usersRef.observeEventType(.Value, withBlock: { snapshot in
//.Value can return multiple nodes within the snapshot so iterate over them
for child in snapshot.children {
let name = child.value.objectForKey("name") as! String
print(name) //prints each users name
}
})
отмечает, что выше присоединяет наблюдатель к узлу пользователей так что любые будущие изменения в пределах этого узла уведомляют приложение и повторно отправить весь узел в приложении
Если вы хотите только одну информации пользователя , и не хочу, чтобы продолжить наблюдение за изменения
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath("users")
let thisUserRef = usersRef.childByAppendingPath("uid_2")
thisUserRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
let name = child.value.objectForKey("name") as! String
print(name) //prints each users name
})
Наконец, для запроса всех ключей, которые принадлежат к uid_0 (который является немного излишним в этом примере, так как мы уже знаем, какие ключи они имеют от своего узла) , Если ключи реф также содержит другую информацию, как имя двери, здание дверь была, или расположение дверей, было бы более целесообразным и требует другую структуру, поэтому предположим, что это так:
ref = myParentNodeName
let keysRef = myParentNodeName.childByAppendingPath("keys")
keysRef.queryOrderedByChild("uid_0").queryEqualToValue(true)
.observeSingleEventOfType(.Value, withBlock: { snapshot in
let doorLocation = child.value.objectForKey("door_location") as! String
print(doorLocation) //prints each users name
})
обратите внимание, что этот код является Swift, так как платформа не была задана в вопросе.
Другой вопрос:
Можем ли мы сделать вложенные запросы? например совместить предыдущее условие с некоторым условием на дверных ключах, чтобы вернуть объект JSON только , относящийся к дверным клавишам, содержащимся в узле «user1»?
Я думаю, вы имеете в виду, можете ли вы запросить uid_2, посмотреть, какие ключи у них есть, а затем загружать информацию из этих конкретных клавиш.
Да! Но ... (всегда есть но)
Firebase является асинхронным, поэтому вы должны учитывать это при вложенных запросах, то есть вам нужно обеспечить возврат всех данных до получения большего количества данных. Так, например, если вам нужны данные ключа uid_2, вы можете наблюдатьSingleEventOfType на узле uid_2. Затем у вас были бы ключи и могли бы наблюдатьSingleEventOfType на каждом ключе.
Технически это будет работать, но с асинхронными данными, летящими вокруг, вы можете получить код, топающий другим кодом и обработкой данных, прежде чем он будет возвращен.
Лучшим вариантом (в моем примере) является просто полностью исключить это и запросить узел ключей для ключей uid_2.
В качестве примечания к примечанию, наблюдение за узлом имеет намного меньше накладных расходов, чем запрос, поэтому, если вы хотите загрузить один узел и знаете путь, используйте функцию наблюдения.