0

so I am working a food list project that I want to pass mealname/mealpic/mealDescription to my tableViewCell from FirebaseDatabase.

it will be something looks like this enter image description here

here's my FirebaesDatabase Structure

enter image description here

and here's my code in the view controller

    override func viewDidLoad() {
    super.viewDidLoad()

    WeekMenu.delegate = self
    WeekMenu.dataSource = self

    let url = GIDSignIn.sharedInstance().currentUser.profile.imageURL(withDimension: 100)
    let data = try? Data(contentsOf: url!)
    userpic.image = UIImage(data:data!)



    DataService.ds.REF_MENUDATA.observe(.value, with: { (snapshot) in
        if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot]

        {
            for snap in snapshot {
                print("SNAP: \(snap)")
                if let menuDict = snap.value as? Dictionary<String, AnyObject> {
                    let date = snap.key
                    let menu = menuContnet(weekmenudate: date, menuData: menuDict as! Dictionary<String, String>)
                    self.menus.append(menu)
                }
            }
        }
    })
    self.WeekMenu.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 5
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let menu = menus [indexPath.row]
    if let cell: WeekMenu = tableView.dequeueReusableCell(withIdentifier: "WeekMenu") as! WeekMenu {
  cell.configureCell(menu: menu)
    return cell
    }  
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    performSegue(withIdentifier: "ToVari", sender: nil)  
    }

It crashed at runtime and throws an "Index out of range" error at line let menu = menus [indexPath.row]

I know this Index out of range error question is kind of FAQ but I did some research myself and they don't really help

could anyone possibly point out what might went wrong ? thanks

UPDATE

now I successfully pass what I have in FirebaseDatabase into my tableview.

but I have 5 nodes from Day1 to Day5 but my tableview shows only one (Day3)

in my func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return menus.count }

why is that happening ?

my class of content is like the following

class menuContnet {


private var _menuKey: String!
private var _mealDes : String!
private var _mealPic : String!
private var _mealname : String!
private var _menuRef: FIRDatabaseReference!


var menuKey: String{
    return _menuKey
}

var mealDes : String {
    return _mealDes
}

var mealname : String {
    return _mealname
}

var mealPic : String {
    return _mealPic
}

init (mealDes: String, mealname: String, mealPic: String) {
    self._mealDes = mealDes
    self._mealname = mealname
    self._mealPic = mealPic
}

init (menuKey: String, menuData : Dictionary <String, String>) {
    self._menuKey = menuKey

    if let mealname = menuData["mealname"]  {
        self._mealname = mealname
    }

    if let mealPic = menuData["mealPic"] {
        self._mealPic = mealPic
    }

    if let mealDes = menuData["mealDes"] {
        self._mealDes = mealDes
    }

    _menuRef = DataService.ds.REF_MENUS.child(_menuKey)

}

}

UPDATE

if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot]            
        {
            for snap in snapshot {

                print ("SNAP: \(snap.key)")

                if  let menuDict = snap.value as? Dictionary<String, String> {
                    let key = snap.key
                    let menu = menuContnet(menuKey: key, menuData: menuDict)
                    print (key)
                    self.menus.append(menu)

                    self.WeekMenu.reloadData()

so at print ("SNAP: (snap.key)") i get all nodes from Day1 to Day 5

but at print (key) i get only Day3

i think the "if let menuDict" statement is causing the problem

and if i get rid of the "if" and make my code looks like this

                    let menuDict = snap.value as? Dictionary<String, String> 
                    let key = snap.key
                    let menu = menuContnet(menuKey: key, menuData: menuDict)
                    print (key)
                    self.menus.append(menu)

                    self.WeekMenu.reloadData()

it crashed at runtime throwing "unexpectedly found nil while unwrapping an Optional value" error

I think I'm getting there, I will keep doing some more research

any tips is appreciated

Ian
  • 239
  • 1
  • 14

1 Answers1

0

Try :-

DataService.ds.REF_MENUDATA.observe(.value, with: { (snapshot) in
    if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot]

    {
        for snap in snapshot {
            print("SNAP: \(snap)")
            if let menuDict = snap.value as? Dictionary<String, AnyObject> {
                let date = snap.key
                let menu = menuContnet(weekmenudate: date, menuData: menuDict as! Dictionary<String, String>)
                self.menus.append(menu)
                self.WeekMenu.reloadData()  // This will reload your table to show your newly appended cell one at a time.
            }
     /*

          if menus.count == snap.childrenCount {
                self.WeekMenu.reloadData()     //Will only reload your table after your entire requested database has been retrieved
                 }
     */
        }
    }
})

And change your :-

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return menus.count ?? 0
    }
Dravidian
  • 9,945
  • 3
  • 34
  • 74
  • hi Dravidian, Thanks for replying. I tried your code, the error goes away. But nothing shows on my tableview...i guess the data in firebase didn't passed in. do you need my other Model file or view controller ? – Ian Oct 18 '16 at 14:28
  • So I successfully pass data in FirebaseDatebase by following your code, – Ian Oct 19 '16 at 10:06
  • but it shows only one cell while i have 5 nodes in Firebase database.... i have updated the question. I don't really know what the problem is :( – Ian Oct 19 '16 at 10:07
  • Are you sure you are being able to recieve all 5 nodes, try printing. – Dravidian Oct 19 '16 at 10:14
  • so i update the question again, I think I'm getting there – Ian Oct 19 '16 at 16:13
  • Dont loose the `if` statement , jus replace `Dictionary` to `[String:AnyObject]` – Dravidian Oct 19 '16 at 16:27
  • Hi, if I do that, it still ask me to append Dictionary to menuDict in the following line – Ian Oct 20 '16 at 02:10
  • Accept this as answer if it solved your issue :) Happy Coding – Dravidian Oct 23 '16 at 16:36