5
votes

I am trying to get data from Firebase, I have tried like this:

FIREBASE_REF.childByAppendingPath("tasks").observeEventType(.Value, withBlock: { (snapshot) -> Void in
            print(snapshot.value)
            self.tasks = [Task]()
            var task = Task()
            let data = snapshot.value as! NSDictionary
            let tasksFromServer = data.allValues as! [NSDictionary]
            for taskFromServer in tasksFromServer {
                task.description = taskFromServer.objectForKey("description") as! String
                task.startTime = taskFromServer.objectForKey("startTime") as! String
                task.endTime = taskFromServer.objectForKey("endTime") as! String
                task.progress = taskFromServer.objectForKey("progress") as! Int
                let priorityTemp = taskFromServer.objectForKey("priority") as! Int
                switch priorityTemp {
                case 0: task.priority = .Low
                case 1: task.priority = .Medium
                case 2: task.priority = .High
                default: break
                }
                task.assignee = taskFromServer.objectForKey("assignee") as! String
                self.tasks.append(task)
            }
            MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
            self.tableView.reloadData()
        }

but it shows error in this line:

let data = snapshot.value as! NSDictionary

It says: Could not cast value of type '__NSArrayM' (0x10ebfc8d8) to 'NSDictionary' (0x10ebfcd60).

My data from Firebase like this:

enter image description here

But in other side, I use another code in another ViewController to get users name and role from Firebase, it works.

FIREBASE_REF.childByAppendingPath("users").observeEventType(.Value, withBlock: { (snapshot) -> Void in
            self.names = []
            self.roles = []
            let data = snapshot.value as! NSDictionary
            let employees = data.allValues as! [NSDictionary]
            for employee in employees {
                let name = (employee.objectForKey("firstName") as! String) + " " + (employee.objectForKey("lastName") as! String)
                self.names.append(name)
                let role = employee.objectForKey("position") as! String
                self.roles.append(role)
            }
            MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
            self.collectionView.reloadData()
        }) 

enter image description here

But why the first code always crash.

Any helps would be appreciated. Thanks.

1
Well, it seems that snapshot.value is a NSArray and not a NSDictionary (according to your error message), so let data = snapshot.value as! NSArray, and modify the other lines according to this change.Larme
May you check my update question again, It works with another code.Khuong
I don't use FireBase and don't speak Swift, so, it's just guess, but did you notice that with employeemanager, there is task, and the a 0 that may lead to indicate that's at index 0 (as an array would have), you get a dictionary with "assignee", etc.Larme
0 after tasks that you said means the id of each task. If you look the tasks and users, their's structure is almost similar, so why one code run well, but why another code cause crash.Khuong
It's usually a bad idea to name your keys as integer digits (like an array) - you'll be much better off to have firebase create the keys via childByAutoId and then store your tasks within each one - very similar to your /users structure. If you need ordering, do that as a child value or perhaps a timestamp.Jay

1 Answers

1
votes

Firebase transforms your dictionary object to an array if more than 50% of keys are between 0 and maximum key (exactly your case with one zero element).

https://www.firebase.com/docs/ios/guide/understanding-data.html#section-arrays-in-firebase