Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(setValue:) Cannot store object of type _SwiftValue at pictureURL. Can only store objects of type NSNumber, NSString, NSDictionary, and NSArray

Having some issues understanding firebase with Swift 3.

I've remade my observer to look like this:

  currentUserFirebaseReference.observeSingleEvent(of: .value, with: { (snapshot: FIRDataSnapshot) in
            let UID = snapshot.key

   let dict = snapshot.value as! Dictionary<String,AnyObject>
   let pictureURL = dict["pictureURL"] as! String

I used to just do

observation..... in {

let picture = snapshot.value!["pictureURL"]

But now I guess you have to explicitly tell Firebase that you're dealing with a Dictionary?

My problem then comes when I'm trying to set a value.

I'm adding the pictureURL from above to a Person class, and later I'm doing:

 let picURL = self.currentUserInfo.pictureURL // The picture from before

  let info = ["pictureURL" : picURL, ....morestuff] as [String : Any] // Swift conversion added the String:Any bit. Assume this is correct?

ref.setValue(info)

and I get this error:

Terminating app due to uncaught exception 'InvalidFirebaseData', reason: '(setValue:) Cannot store object of type _SwiftValue at pictureURL. Can only store objects of type NSNumber, NSString, NSDictionary, and NSArray.

Why is this happening and how can I fix it?

edit:

So I found out this only happens when trying to pull info from a class.

    let data : Dictionary<String, Any> = ["Cats" : 3, "Dogs" : 9]

    DataService.ds.REF_BASE.child("testing").setValue(data)

The above code works.

   class Dog {
       var fur : String?
    }

    let dog = Dog()
    dog.fur = "Brown"

    let data : Dictionary<String, Any> = ["Cats" : 3, "Dogs" : 9, "DogFur" : dog.fur]

    DataService.ds.REF_BASE.child("testing").setValue(data)

That code crashes and says I can't assign a swiftvalue type.

like image 490
user6820041 Avatar asked Sep 14 '16 07:09

user6820041


1 Answers

It looks like Firebase is wanting us to be very specific with your data types with Swift 3.

We need to straight up tell Swift what kind of dictionary we're going to have. In most cases it'll probably be

Dictionary<String, Any>

"Any" is a new thing in Swift 3 I think. AnyObject doesn't work here because Swift redefined what AnyObjects are, and Strings/Ints dont seem to be them anymore.

Finally, it seems like we have to have absolutely no optionals in your dictionary. Maybe an optional is a _SwiftValue? Once I got rid of optionals and garunteed each value was going to be there it started working for me.

like image 88
user6820041 Avatar answered Nov 19 '22 16:11

user6820041