Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert document to a custom object in Swift 5?

I've been trying to convert the document retrieved from the Firebase's Cloud Firestore to a custom object in Swift 5. I'm following the documentation:

  • https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects

However, Xcode shows me the error Value of type 'NSObject' has no member 'data' for the line try $0.data(as: JStoreUser.self). I've defined the struct as Codable.

The code:

func getJStoreUserFromDB() {
    db = Firestore.firestore()
    let user = Auth.auth().currentUser
    db.collection("users").document((user?.email)!).getDocument() { 
        (document, error) in
        let result = Result {
            try document.flatMap {
                try $0.data(as: JStoreUser.self)
            }
        }
    }
}

The user struct:

public struct JStoreUser: Codable {
    let fullName: String
    let whatsApp: Bool
    let phoneNumber: String
    let email: String
    let creationDate: Date?
}

The screenshot:

The screenshot

Does anyone know how to resolve this?

like image 246
Tianyao Chen Avatar asked Dec 31 '19 22:12

Tianyao Chen


1 Answers

You need to initialize your struct and then you can extend the QueryDocumentSnapshot and QuerySnapshot like:

extension QueryDocumentSnapshot {
    func toObject<T: Decodable>() throws -> T {
        let jsonData = try JSONSerialization.data(withJSONObject: data(), options: [])
        let object = try JSONDecoder().decode(T.self, from: jsonData)
        
        return object
    }
}

extension QuerySnapshot {
    
    func toObject<T: Decodable>() throws -> [T] {
        let objects: [T] = try documents.map({ try $0.toObject() })
        return objects
    }
}

Then, try to call the Firestore db by:

db.collection("users").document((user?.email)!).getDocument() { (document, error) in
    guard error == nil else { return }
    guard let commentItem: [CommentResponseModel] = try? document.toObject() else { return }
     // then continue with your code
}
like image 145
sangak Avatar answered Oct 31 '22 13:10

sangak