2017-02-10 3 views
0

Как я могу получить доступ к информации, находящейся на «более глубоком» уровне моментального снимка? Всегда ли нужно начинать другой запрос? Чтобы показать вам, что я имею в виду, у меня есть скриншот из моей структуры: Screenshot of DataStructureВложенные данные в Firebase

Я загружаю все сообщения в свой запрос, могу прочитать информацию об авторе и т. Д., Но как я могу получить информацию внутри опций? Я попытался следующие:

ref.child("posts").child("details").observe(.childAdded, with: { (snapshot:FIRDataSnapshot) in 

     if snapshot.value == nil { 
      return 
     } 
     let post = Post() 
     guard let snapshotValue = snapshot.value as? NSDictionary else { 
      return 
     } 
     post.postID = snapshot.key 
     post.title = snapshotValue["title"] as? String 
     post.postDescription = snapshotValue["description"] as? String 
     if (post.postDescription == ""){ 
      post.postDescription = "No description has been entered for this post.." 
     } 
     post.timestamp = snapshotValue["timestamp"] as? NSNumber 

     let options = snapshotValue["options"] 
     print(options) 

при печати вариантов, я могу видеть информацию, но когда я пытаюсь бросить его NSDictionary или что-то, чтобы получить доступ к нему, он печатает ноль? Я также могу определить новый атрибут, например post.options, если это может помочь? Параметры не всегда равны 0 и 1, его переменная, поэтому мне нужно прокручивать их. Как я могу это достичь?

+0

Если я правильно понял, 'print (options)' на самом деле печатает ваши данные, верно? Кажется, из образа, что параметры являются массивом, поэтому, если вы переводите его в словарь, это не сработает. Может быть, итерации через параметры с помощью ... для каждого цикла и распечатать содержимое, чтобы узнать, получаете ли вы свои данные. – Prientus

+0

ok. Я попробую, что –

+0

Мне нужно каким-то образом его отличить, в противном случае параметры имеют тип Any? .. поэтому я могу " t используйте каждый цикл для типа any –

ответ

0

Вслед за замечания по первоначальному вопросу, вы можете получить доступ к значениям опции, как это:

if let options = snapshotValue["options"] as? [Any] { 
    for option in options { 
     if let optionDict = option as? [String:Any] { 
      let votes = optionDict["votes"] as? Int 
      let url = optionDict["uri"] as? String 
     } 
    } 
} 
+0

@cloo_coder Нет, нет. Это не очень хороший ответ. Хотя он будет работать * иногда *, что, если параметры - это String или Bool? Вы предполагаете, что параметры - это словарь, который он * не * - это массив Firebase, которого в общем следует избегать [Массивы зла] (https://firebase.googleblog.com/2014/04/best-practices-arrays -in-firebase.html) – Jay

+0

@Jay Вы правы, что mainArray является неправильным и случайным, и я изменил его на 'options', как и должно быть. То, что я не понимаю, - это то, что OP знает, что 'options' является дочерним элементом Firebase, который, как он знает, является списком элементов, почему он не может рассматривать его как' [Any] '? – Prientus

+0

snapshotValue не имеет значения ["options"], если он определен как Any. Запустите код самостоятельно, и вы увидите, что параметры всегда равны структуре OP. – Jay

0

Вот очень упрощенный ответ, который будет работать со структурой Firebase представленной (обратите внимание, что Firebase массив должен быть только используется в конкретных случаях и, как правило, следует избегать).

данной структуре

posts 
    post_id_0 
    caption: "some caption" 
    comment: "some comment" 
    options: 
     0: 
      votes: "10" 
      url: "some url" 
     1: 
      votes: "20" 
      url: "some url" 

к сведению, что структура похожа на ОР в том, что параметры дочернего узла является Firebase массив, где каждый индекс содержит также дочерние узлы. Таким образом, ключ является индексом (0, 1, 2), а каждый из них является словарем ключа: значения пар (голосов: значение и URL: значение)

Следующий код будет читаться на этом конкретном узле, распечатать подпись и комментарии, а затем итерации по массиву опций и печать голоса и URL для каждого ребенка в массиве

ref.child("posts").child("post_id_0") 
        .observeSingleEvent(of: .value, with: { snapshot in 
    //treat the whole node as a dictionary 
    let postDict = snapshot.value as! [String: Any] 

    //and since it's a dictionary, access each child node as such  
    let caption = postDict["caption"] as! String 
    let comment = postDict["comment"] as! String 

    print("caption: \(caption) comment: \(comment)") 

    //the options child node is an array of indexes, each with 
    // a dictionary of child nodes  
    let options = postDict["options"] as! [[String:Any]] //array of dictionaries 

    //now iterate over the array  
    for option in options { 
      let votes = option["votes"] //each option child is a dict 
      let url = option["url"] 
      print("votes \(votes!) url: \(url!)") 
    } 
}) 

Обратите внимание, что мы указываем структуру опции дочернего узла, как этот

let options = postDict["options"] as! [[String:Any]] 

который представляет собой массив ключей: значение (String: Any) словарей

Очень важно, чтобы весь узел параметров был прочитан для работы с ним. Если детей 10 тыс. Человек, он становится крайне неэффективным. Это также не запрашивается, поэтому, если вы хотите подсчитать, сколько дублирующих URL-адресов есть, весь узел должен быть прочитан, а затем проанализирован.

Лучшего варианта является использование childByAutoId для создания узлового ключа имен

posts 
    post_id_0 
    caption: "some caption" 
    comment: "some comment" 
    options: 
     -Yuijjismisdw 
      votes: "10" 
      url: "some url" 
     -YJ989jijdmfm 
      votes: "20" 
      url: "some url" 

Yuijjismisdw был создан с childByAutoId.

Смежные вопросы