Firebase(Cloud Firestore)-如何在Swift 5中将文档转换为自定义对象?

时间:2019-12-31 22:22:12

标签: ios swift firebase google-cloud-firestore

我一直试图将从Firebase的Cloud Firestore检索到的文档转换为Swift 5中的自定义对象。(我在关注文档:https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects)。但是,Xcode向我显示了行Value of type 'NSObject' has no member 'data'的错误try $0.data(as: JStoreUser.self)。我已将结构定义为Codable。有谁知道如何解决这个问题?谢谢!

代码:

    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)
                }
            }
        }

    }

用户结构:

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

The screenshot

3 个答案:

答案 0 :(得分:16)

与Firebase团队联系后,我找到了所需的解决方案。事实证明,我必须显式地执行import FirebaseFirestoreSwift而不是仅仅进行import Firebase。此后错误将消失。 (当然,您首先需要将Pod添加到您的Podfile中:D)

答案 1 :(得分:0)

您可以如下所示进行操作:-

首先创建模型类:-

import FirebaseFirestore
import Firebase

//#Mark:- Users model
struct CommentResponseModel : Equatable {

    var createdAt : Date?
    var commentDescription : String?
    var documentId : String?

    var dictionary : [String:Any] {
        return [
                "createdAt": createdAt  ?? "",
                "commentDescription": commentDescription  ?? ""
        ]
    }

   init(snapshot: QueryDocumentSnapshot) {
        documentId = snapshot.documentID
        var snapshotValue = snapshot.data()
        createdAt = snapshotValue["createdAt"] as? Date
        commentDescription = snapshotValue["commentDescription"] as? String
    }
}

然后您可以将firestore文档转换为自定义对象,如下所示:-

func getJStoreUserFromDB() {
    db = Firestore.firestore()
    let user = Auth.auth().currentUser
    db.collection("users").document((user?.email)!).getDocument() { (document, error) in
        //        Convert firestore document your custom object
        let commentItem = CommentResponseModel(snapshot: document)
    }
}

答案 2 :(得分:0)

您需要初始化结构,然后可以扩展QueryDocumentSnapshot和QuerySnapshot,如下所示:

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
    }
}

然后,尝试通过以下方式调用Firestore数据库:

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
}