1

I have three nodes in firebase that I would like to loop through using the same loop. I'm successfully able to loop through a single node (cookies) using this code:

databaseRef.child("cookies").observeSingleEvent(of: .value, with: {(snapshot) in
         for item in snapshot.children.allObjects as! [DataSnapshot] {
            let thisItem = item.value as! NSDictionary

            if(favoriteArray.contains(item.key)) {

             self.numberOfRecipes.append(thisItem["recipeHeaderFirebase"] as! String)

             let tempRecipe = Recipe()
             tempRecipe.fbKey = item.key
             tempRecipe.recipeHeaderObject = (thisItem["recipeHeaderFirebase"] as! String)
             tempRecipe.recipeTextObject = (thisItem["recipeIngredientsTextFirebase"] as! String)
             tempRecipe.recipeImageObject = (thisItem["recipeImageFirebase"] as! String)

             self.recipeClassArray.append(tempRecipe)
         }   
    }
})

I would now like to loop the two remaining nodes as well. Any Ideas?

I tried adding additional nodes, but a print in the console shows that it only adds from the last node. See code below:

     self.databaseRef.child("cookies").observeSingleEvent(of: .value, with: {(snapshot) in
        self.databaseRef.child("dessert").observeSingleEvent(of: .value, with: {(snapshot) in self.databaseRef.child("breakfast").observeSingleEvent(of: .value, with: {(snapshot) in
         for item in snapshot.children.allObjects as! [DataSnapshot] {
            let thisItem = item.value as! NSDictionary

            if(favoriteArray.contains(item.key)) {

             self.numberOfRecipes.append(thisItem["recipeHeaderFirebase"] as! String)

             let tempRecipe = Recipe()
             tempRecipe.fbKey = item.key
             tempRecipe.recipeHeaderObject = (thisItem["recipeHeaderFirebase"] as! String)
             tempRecipe.recipeTextObject = (thisItem["recipeIngredientsTextFirebase"] as! String)
             tempRecipe.recipeImageObject = (thisItem["recipeImageFirebase"] as! String)

             self.recipeClassArray.append(tempRecipe)
         }

    }
        print(self.numberOfRecipes.count)
            print(self.recipeClassArray)

            let url = URL(string: self.recipeClassArray[self.currentView].recipeImageObject)
            self.recipeImageUI.kf.setImage(with: url)           //SÄTTER IN BILD MED KINGFISHER

            self.recipeHeader.text = self.recipeClassArray[self.currentView].recipeHeaderObject //SÄTTER IN HEADER

            self.ingredientText.text = self.recipeClassArray[self.currentView].recipeTextObject //SÄTTER IN TEXTEN


            self.animateFunc(image: self.recipeImageUI, labelHeader: self.recipeHeader, labelText: self.ingredientText) //FUNKTION FÖR ATT ANIMERA     
    }) 
  })  
})
Joakim Sjöstedt
  • 824
  • 2
  • 9
  • 18
  • You can embed the observes into each other. For example, something like that: databaseRef.child("cookies").observeSingleEvent(of: .value, with: {(snapshot) in databaseRef.child("secondNode").observeSingleEvent(of: .value, with: {(snapshot) in ... and so on. This is technically not one loop but the data access happening one after another –  Oct 12 '17 at 21:36
  • Thanks, but I did a print in the console and it only seems to add from the last node, ignoring the first two listed... Updating my post above :) Can you see what's missing? – Joakim Sjöstedt Oct 12 '17 at 21:59
  • Yes, because the print only called at the deepest level... so try something like that: self.databaseRef.child("cookies").observeSingleEvent(of: .value, with: {(cookiesSnapshot) in print("cookies: \(cookiesSnapshot)") self.databaseRef.child("dessert").observeSingleEvent(of: .value, with: {(dessertSnapshot) in print("dessert: \(dessertSnapshot)") self.databaseRef.child("breakfast").observeSingleEvent(of: .value, with: {(breakfastSnapshot) in print("breakfast: \(breakfastSnapshot)") –  Oct 12 '17 at 22:31
  • Awesome man, thanks for your help! :) – Joakim Sjöstedt Oct 14 '17 at 09:31

2 Answers2

1

The following code prints all three levels of snapshots. I hope this will help:

self.databaseRef.child("cookies").observeSingleEvent(of: .value, with: { (cookiesSnapshot) in
    print("cookies snapshot: \(cookiesSnapshot)")

    self.databaseRef.child("dessert").observeSingleEvent(of: .value, with: { (dessertSnapshot) in 
        print("dessert snapshot: \(dessertSnapshot)")

        self.databaseRef.child("breakfast").observeSingleEvent(of: .value, with: { (breakfastSnapshot) in
            print("breakfast snapshot: \(breakfastSnapshot)")
        })
    })
})

I can't check this, so I hope all the } and ) are at the right place. :)

1

You can convert snapshot to dict and loop through the dict:

databaseRef.child("cookies").observeSingleEvent(of: .value, with: { snapshot in
    if let dict = snapshot.value as? Dictionary<String, Dictionary<String, Any>> {
        for (key, value) in dict {
            if let recipeHeader = value["recipeHeaderFirebase"] as? String, favoriteArray.contains(key) {
                self.numberOfRecipes.append(recipeHeader)
             ...
            }
        }
    }
}

or you can use the enumerator:

databaseRef.child("cookies").observeSingleEvent(of: .value, with: { snapshot in
    let enumerator = snapshot.children
    while let (key, value) = enumerator.nextObject() as? FIRDataSnapshot {
        if let recipeHeader = value["recipeHeaderFirebase"] as? String, favoriteArray.contains(key) {
            self.numberOfRecipes.append(recipeHeader)
            ...
        }
    }
}
Vitalii
  • 4,267
  • 1
  • 40
  • 45