我一直试图将从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?
}
答案 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
}