Marian Petrisor
Marian Petrisor

Reputation: 302

Firebase looping multi level nodes

I am trying to get results from a node that has one more level of nodes and cannot get through it:

I am retrieving the data like this (it works perfectly but not for the node called "items"):

func fetchMeals() {
    print("start pulling data")

    let user = Auth.auth().currentUser?.uid

    ref.child("Users_Food_Data").child(user!).queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in

        if snapshot.value as? [String : AnyObject] != nil {

            let allMeals = snapshot.value as! [String : AnyObject]
            self.foodArray.removeAll()

            for (_, value) in allMeals {

                let foodToShow = FoodStruct()


                if let calories = value["calories"] as? String,
                    let itemCarbs = value["energy"] as? String,
                    let itemProteins = value["proteins"] as? String,
                    let itemFat = value["fat"] as? String,
                    let date = value["date"] as? String,
                    let id = value["id"] as? String,
                    let name = value["name"] as? String,
                    let interval = value["interval"] as? Int {
                    foodToShow.itemKcal = calories
                    foodToShow.itemCarbs = itemCarbs
                    foodToShow.itemProteins = itemProteins
                    foodToShow.itemFat = itemFat
                    foodToShow.id = id
                    foodToShow.interval = interval
                    foodToShow.date = date
                    foodToShow.itemName = name



                    self.foodArray.append(foodToShow)
                    self.collectionView?.reloadData()
                }

                self.breakfastArray.sort(by: {$0.interval! > $1.interval!})



            }
        }

        })
}

And the database looks like this:

"Users_Food_Data" : {
"JztkBihGgda0jtSpe6pNwt8hZu13" : {
  "Breakfast:23 Sep 2017" : {
    "calories" : "1145.0",
    "date" : "23 Sep 2017",
    "energy" : "238.8",
    "fat" : "3.0",
    "id" : "-Kukx_9lSpCh3lcEMzap",
    "interval" : 1.506207565807117E9,
    "items" : {
      "-KukxKAntXDaS__v3ZLA" : {
        "calories" : "30",
        "date" : "23 Sep 2017",
        "energy" : "6",
        "fat" : "0.1",
        "interval" : 1.506207500336909E9,
        "itemKey" : "-KukxKAntXDaS__v3ZLA",
        "mealKey" : "-KukxKAntXDaS__v3ZLB",
        "name" : "Strawberries",
        "proteins" : "0.8",
        "quantity" : "3"
      },
      "-KukxLYmyg32lU1D3Wh3" : {
        "calories" : "29",
        "date" : "23 Sep 2017",
        "energy" : "9",
        "fat" : "0.5",
        "interval" : 1.506207505968336E9,
        "itemKey" : "-KukxLYmyg32lU1D3Wh3",
        "mealKey" : "-KukxLYmyg32lU1D3Wh4",
        "name" : "Lemon",
        "proteins" : "1.1",
        "quantity" : "1"
      }
    },
    "name" : "Breakfast",
    "proteins" : "17.0"
  },
  "Breakfast:24 Sep 2017" : {
    "calories" : "959.0",
    "date" : "24 Sep 2017",
    "energy" : "106.4",
    "fat" : "46.1",
    "id" : "-KunWOZeSxW9eCIA6O1z",
    "interval" : 1.506250519537633E9,
    "items" : {
      "-KulrJq6jOpsG6oiJuDM" : {
        "calories" : "458",
        "date" : "24 Sep 2017",
        "energy" : "4.6",
        "fat" : "45",
        "interval" : 1.506222704055992E9,
        "itemKey" : "-KulrJq6jOpsG6oiJuDM",
        "mealKey" : "-KulrJq6jOpsG6oiJuDN",
        "name" : "Coconut",
        "proteins" : "4",
        "quantity" : "1"
      },

How do I do that when I know only "Users_Food_Data" and user ID. I just want to list them in the apropiate cells.

Upvotes: 2

Views: 175

Answers (1)

Arrabidas92
Arrabidas92

Reputation: 1153

Here is my suggestion.

First looking on your database structure, you currently have something like this :

Users_Food_Data
|_userid
  |_FoodStruct
    |_items
      |_id_1
        |_data like calories, date...
      |_id_2
        |_data...

There is too much nodes and this kind of hierarchy doesn't respect what we call Denormalization. Remember that Firebase database is like a NoSQL database and it's a big difference compared to SQL classic databases. Here is an explanation to the best practice to denormalize your database structure : Structure your database

What i can suggest is structure your database more like this :

One node :
UsersFood
|_userid
  |_breakfeast_id_1
  |_breakfeast_id_2...

2nd node
Breakfeasts
|_breakfeast_id_1
  |_item_id_1
  |_item_id_2...

3rd node
Items
|_item_id_1
  |_calories
  |_date
  |_energy...

Then in your code, you can :

  1. Observe with a single event on UsersFood node all the breakfeast ids
  2. Then with all breakfeast ids get items_id
  3. Finally get items_id data

Hope it will help you through your code.

Edit 1 : You can also loop through a child node by using this :

for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
     //DO WHAT YOU NEED TO DO
}

Upvotes: 1

Related Questions