Search code examples
iosswiftfirebasefirebase-realtime-databaseinitializer

Initialize an object to take in optional values on Firebase with Swift


I'm comfortable with initializing objects in general but my method only seems to work when all parameters must exist on the database. I have looked at this which works. But I now don't know how to initialize it with a nest array.

This is how I would normally initialise an object:

class User {

    var firstName: String
    var lastName: String
    var summary: String?
    var groups = [Group]()
    var ref: DatabaseReference?
    var key: String

    init?(from snapshot: DataSnapshot) {

        let snapshotValue = snapshot.value as? [String: Any]

        guard let firstName = snapshotValue?["firstName"] as? String, let lastName = snapshotValue?["lastName"] as? String, let summary = snapshotValue?["summary"] as? String else { return nil }

        self.firstName = firstName
        self.lastName = lastName
        self.summary = summary
        self.key = snapshot.key

        self.groups(snapshot: snapshot.childSnapshot(forPath: "groups"))

    }

    func groups(snapshot: DataSnapshot) {
        for child in snapshot.children {
            guard let group = child as? DataSnapshot else { continue }
        }
    }

Solution

  • Just don't make the optional properties a part of that guard (that's what prevents the execution to finish it:

    init?(from snapshot: DataSnapshot) {
    
        let snapshotValue = snapshot.value as? [String: Any]
    
        guard let firstName = snapshotValue?["firstName"] as? String,
              let lastName = snapshotValue?["lastName"] as? String else { return nil }
    
        self.firstName = firstName
        self.summary = snapshotValue?["summary"] as? String
        self.key = snapshot.key
    
        self.groups(snapshot: snapshot.childSnapshot(forPath: "groups"))
    
    }
    

    Optionally, you can use if let syntax:

    if let summary = snapshotValue?["summary"] as? String {
        self.summary = summary
    }
    

    But in this case this is simpler:

    self.summary = snapshotValue?["summary"] as? String