Jay
Jay

Reputation: 5084

Casting Firebase Snapshot to Swift 3 object

I am retrieving Objects from the Firebase DB and I need to cast them to a custom struct class object

Class:

struct Request {
    var Address: String!
    var Position: Position!
    var RequestID: String!
    var Status: String!
}

The function that gets the snapshot from my Firebase DB:

self.ref.child("requests").observe(.childAdded, with: { snapshot in

    //I need to cast this snapshot object to a new Request object here

    let dataChange = snapshot.value as? [String:AnyObject]

    print(dataChange)

})

How can I get this done?

Upvotes: 2

Views: 4904

Answers (2)

IvanPavliuk
IvanPavliuk

Reputation: 1810

If your struct has a lot of fields, it's easier to do like this (Swift 4+):

struct Request: Decodable {
    var Address: String
    var RequestID: String
    var Status: String
}

self.ref.child("requests").observe(.childAdded, with: { snapshot in
    guard let data = try? JSONSerialization.data(withJSONObject: snapshot.value as Any, options: []) else { return }
    let yourStructObject = try? JSONDecoder().decode(Request.self, from: data)
}

Upvotes: 6

Jay
Jay

Reputation: 35667

A couple of things. Firebase doesn't have objects - it's a JSON structure. When you get the snapshot.value like so:

let dataChange = snapshot.value as? [String:AnyObject]

The [String: AnyObject] is defining the data as a Dictionary.

You can then access the key:value pairs in dataChange like this

let address = dataChange["address"]

and

let position = dataChange["position"]

From there you can either create new objects and populate them within the closure (adding them to an array for example) or put more intelligence in the object and pass the dictionary and let the object populate itself.

The following is pseudo code but it presents the process:

//create the object and populate it 'manually'
self.ref.child("requests").observe(.childAdded, with: { snapshot in

    let dataChange = snapshot.value as? [String:AnyObject]

    let aRequest = Request()
    aRequest.address = dataChange["address"]
    aRequest.position = dataChange["position"]
    self.requestArray.append(aRequest)
})

or

Class Request {

   var address = ""
   var position = ""

   func initWithDict(aDict: [String: AnyObject]) {
    self.address = aDict["address"]
    self.position = aDict["position"]
   }

}

//let the object populate itself.
self.ref.child("requests").observe(.childAdded, with: { snapshot in

    let dataChange = snapshot.value as? [String:AnyObject]
    let aRequest = Request(initWithDict: dataChange)
    self.requestArray.append(aRequest)
})

Upvotes: 6

Related Questions