title: Access Nested Data Using Firebase in Swift 3
body: <p>Having trouble loading nested data from Firebase in Swift 3.</p>
  
  <p>After 6 hours of struggle and reading anything I could find, I still have no solution. My database looks like this:</p>
  
  <p><a href="https://i.stack.imgur.com/wnK2X.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/wnK2X.jpg" alt="firebase data"></a></p>
  
  <p>The data is a bunch of questions, each of which has one or more answers. I can get the basic question data ok, but can't access the answer data.</p>
  
  <p>In my code below you can see how I get the basic question data.   I am stuck as to how to access the set of answers that I have in hand when I fetch the Question.  I am trying to avoid another database lookup to fetch the answers because I get them when I fetch the question.  I show in the code what i tired and how it failed (compile or runtime).  Can't see how to get at the data i have in hand for answers</p>
  
  <p>Here are the print results of the debug. You can see that in both attempts I successfully get the key (which I need) and I successfully get a value that looks just like a Dictionary but I am unable to use it as a Dictionary.</p>
  
  <pre><code>------------------
  Attempt #1
  ------------------
  answer (-KZwfXU9inu4ozSjVBwS, {
      isCorrect = 1;
      text = "sample text data";
  })
  ------------------
  key .... -KZwfXU9inu4ozSjVBwS
  ------------------
  value ....{
      isCorrect = 1;
      text = "sample text data";
  }
  ------------------
  
  ------------------
  Attempt #2
  ------------------
  key .... -KZwfXU9inu4ozSjVBwS
  ------------------
  value ....{
      isCorrect = 1;
      text = "sample text data";
  }
  ------------------
  </code></pre>
  
  <p>The code ....</p>
  
  <pre><code>    // point at the database
      let refDB  = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
      // point at Questions
      let questionsRef = refDB.child("questions")
      // filter questions to where the TopicRef is equal to the one provided
       questionsRef.queryOrdered(byChild: "topicRef").queryEqual(toValue: topicRef).observeSingleEvent(of: .value, with:  { (snapshot) in
  
          if snapshot.value is NSNull {
              print("load questions - none found")
          } else {
              for child in snapshot.children {
  
                  let snap = child as! FIRDataSnapshot //each child is a snapshot
  
                  if snap.value != nil {
                      let key = snap.key
  
                      // Skip if fail to get the dictionary
                      guard let dict = snap.value as! [String: Any]? else {
                          print("bad snapshot in load questions")
                          continue
                      }
  
                      // Get the basic question information
                      var text = ""
                      var imageURL = ""
                      var answers = [Answer]()
  
                      // make sure that we don't choke on missing data in question
  
                      // GET text
                      if let textx = dict["text"] as! String? {
                          text = textx
                      } else {
                          print("missing name in question \(key)")
                      }
  
                      // GET image URL
                      if let imageURLx = dict["url"] as! String? {
                          imageURL = imageURLx
                      } else {
                          print("no image URL in question \(key)")
                      }
  
  
                      // load the aswers
                         if let answerDict = dict["answers"] as!  NSDictionary? {
                          // Attempt #1
                          for answer in answerDict {
                              print("------------------")
                              print("Attempt #1")
                              print("------------------")
                              print("answer \(answer)")
                              let akey = answer.key
                              let avalue = answer.value
                              print("------------------")
                              print("key .... \(akey)")
                              print("------------------")
                              print("value ....\(avalue)")
                              print("------------------")
  
                              // Attempt 1A
                              /*  Try cast answer to Dictionary. FAILS
                                  This fails to compile with "can not down cast from NSDictionary.Iterator.Element
                                  to more optional type [String,: Any]"
  
                               if let newDict = answer as! [String: Any]? {
  
                               }
                              */
  
                              // Attempt 1B - tired to see if i could approach avalue as JSON - FAILS
                              /* This compiles - but crashes at runtime "Could not cast value of type '__NSDictionaryM' to 'NSData'"
                              do {
                                  let JSON = try JSONSerialization.jsonObject( with: avalue as! Data, options:JSONSerialization.ReadingOptions(rawValue: 0))
                                  print("JSON .... \(JSON)")
                              } catch let JSONError as NSError {
                                  print("error")
                              } 
                              */
  
                              // Attempt 1C
                              // avalue looks like a dictionaty so try to use t like one
                              //  fails to compile - "type Any has no subscript members"
                              /*
                              let answerText = avalue["text"]
                              */
  
  
                              // Attempt 1D
                              /*  Since avalue looks like a Dictionary try to make it a Dictionary. FAILS
                               This fails to compile with "can not down cast from Any
                               to more optional type [String,: Any]"
  
                               if let newDict = avalue as! [String: Any]? {
  
                               }*/
  
                          }
  
                          print(" ")
                          // Attempt #2
                          for (key, value) in answerDict {
  
                              print("------------------")
                              print("Attempt #2")
                              print("------------------")
                              print("key .... \(key)")
                              print("------------------")
                              print("value ....\(value)")
                              print("------------------")
  
                              // This also fails to compile - cant downcast form Any to [String, Any]
                              /*
                              if let newDict = value as! [String: Any]? {
  
                              } */
  
                              // I likewise can not cast 'value' to anything at all.. The next bit below fails to compile with "cannot downcase from Any to more optional type NSDictionary
                              // Try to make the 'value' in to its own NSDictionay as it looks like a Dictionary
                              /*
                              if let newNSDictionary = value as! NSDictionary? {
  
                              }
                              */
  
                          }
  
                      }
  
                  } else {
                      print("bad snap in trying to load questions")
                  }
  
              }
          }
      })
  </code></pre>
  
  <p>I also tried to cast the original <code>dict["answers"]</code> to other things (besides NSDictionary), but all failed to compile or crashed at runtime.  dict["answers"] could be a bunch of answers so I need to iterate. The iteration works but I can only get key and value. I can NOT get at the inside of value - which at each iteration looks like a Dictionary. At runtime the crash tells me that the 'value' for <code>dict["answers"]</code> wants to be cast to NSDictionary. I have done this but now when I iterate the value at each iteration is type Any. I have not been able to cast 'value' at the iteration to anything I can use to get at the data for each answer. </p>
  
  <pre><code>if let answerDict = dict["answers"] as!  NSDictionary? {
  </code></pre>
  
  <p>Appreciate any pointers to use the value data I have in hand (in value) and can see in print but can not access the key/value pairs programatically.</p>