7

Предупреждение:Как представить отношения двух путей в дереве JSON Firebase?

  • это упражнение, чтобы лучше понять структуру базы данных JSON в Firebase
  • это не обязательно реалистично

У меня есть отношения двумя способами между пользователями и ключами двери. Я хотел бы понять:

  • как представить эти отношения визуально (я могу себе это представить только в виде двух отдельных деревьев)
  • , как это будет работать на Firebase, как бы пользователей и от двери ключи являются дочерними элементами родительского узла «myparentnodename»?
  • Если я моделирую базу данных таким образом, она чувствует себя крайне неэффективной, потому что каждый раз, когда я запрашиваю дочерние узлы «пользователи», я возвращаю всех пользователей. Или я ошибаюсь? Возможно ли только вернуть соответствие данных конкретному пользователю? Например. получить пользователя, где «user = user1»? Можем ли мы выполнять вложенные запросы? например совместить предыдущее условие с некоторым условием на дверных клавишах, чтобы возвращаемый объект JSON относился только к дверным клавишам, содержащимся в узле «user1»?

enter image description here

ответ

10

Это очень длинный ответ, как ваш вопрос был на самом деле около 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.

В качестве примечания к примечанию, наблюдение за узлом имеет намного меньше накладных расходов, чем запрос, поэтому, если вы хотите загрузить один узел и знаете путь, используйте функцию наблюдения.