Jamie22 Jamie22 - 5 months ago 36
Swift Question

Could not cast value of type '__NSDictionaryM' to custom User Class using new Firebase

I'm attempting to query for a specific user using the new Firebase like so:

DataService.sharedInstance.REF_USERS.queryOrderedByChild("username").queryEqualToValue(field.text).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

if let userDoesNotExist = snapshot.value as? NSNull {
print("No User found!")


} else {
let theUsr = snapshot.value as! User
print(theUsr)


}
}, withCancelBlock: { (error) in
// Error

})


From there I was looking to store the snapshot into its own object and access its values from there. I was attempting to do so by doing this:

class User {

let key: String!
let ref: FIRDatabaseReference?
var username: String!
var email: String!


// Initialize from data snapshot
init(snapshot: FIRDataSnapshot) {
key = snapshot.key
email = snapshot.value!["email"] as! String
username = snapshot.value!["username"] as! String
ref = snapshot.ref
}

func toAnyObject() -> AnyObject {
return [
"email": email,
"username": username,
]
}

}


The problem I'm running into is a crash with the following:

Could not cast value of type '__NSDictionaryM' (0x10239efc0) to 'Scenes.User' (0x100807bf0).


How do I fix this? I don't remember running into this problem on the old Firebase. I need access to the snapshot.value's key and for some reason can't access it by using snapshot.value.key without getting a crash so I figure I'd try passing all the data into it's own object.

Jay Jay
Answer

snapshot.value isn't a User, it's a dictionary (*)

Here's a couple of options - there are many.

let aUser = User()
aUser.initWithSnapshot(snapshot)

then, within the User class, map the snapshot.values to the user properties

or

let aUser = User()
aUser.user_name = snapshot.value["user_name"] as! String
aUser.gender = snapshot.value["gender"] as! String

Oh, and don't forget that by using .Value your snapshot may return multiple child nodes so those will need to be iterated over

for child in snapshot.children {
  let whatever = child.value["whatever"] as! String
}

In your case it's just one user so it's fine they way you have it.

*It could be

NSDictionary
NSArray
NSNumber (also includes booleans)
NSString
Comments