我正在创建一个用于将用户数据保存到Firestore数据库的模型,并使用字典对其进行初始化。根据要更新的字段,我将这些值放在字典中,以便用户模型仅包含某些字段,因此将仅更新数据库中的那些字段。但是,我想以某种方式要求在某些用例中提供某些字段。
*下面的示例是我正在尝试做的一个非常简化的版本* 例如:如果我要保存一个新用户,则要确保我包括姓名,个人资料图像和描述。但是,如果我只是想更新一个字段,那么我就不想要求所有这些字段都包含在内
我有99%的肯定自己会以错误的方式进行攻击,因此可以提供任何帮助。
我当前的用户模型:
struct FirestoreUser {
var id: String
var name: String?
var profileImage: String?
var dictionary: [String: Any]
init(dictionary: [String: Any]) {
self.id = dictionary["id"] as! String
self.name = dictionary["name"] as? String
self.profileImage = dictionary["profileImage"] as? String
self.dictionary = dictionary
}
}
// MARK: Firestore functions
extension FirestoreUser {
typealias Handler = ((Error?) -> Void)?
func saveNewFirestoreUser(then handler: Handler = nil) {
// make sure all necessary variables are set
// if they aren't all set, something went wrong
guard let _ = name, let _ = profileImage else { return }
let firestore = Firestore.firestore()
let ref = firestore.collection("users").document(id)
ref.setData(dictionary) { (error) in
if let error = error {
handler?(error)
}
handler?(nil)
}
}
}
答案 0 :(得分:0)
使用可选值构造struct并传递nil作为您不想更新的参数。 您可以使用以下扩展名稍后将结构转换为字典。
struct FirestoreUser: Codable {
var id: String
var name: String?
var profileImage: String?
}
extension Encodable {
var dictionary: [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] }
}
}
使用-
let test = FirestoreUser(id: "01", name: "Abhinav", profileImage: nil)
print(test.dictionary)
输出-
["name": Abhinav, "id": 01]
答案 1 :(得分:0)
在实时数据库中,如果您只想更新子项,请使用 updateChildValues 而不是setValue。我相信Firestore中有类似的东西。
实时数据库答案:
更新
self.ref.child("users/\(user.uid)/username").setValue(username)
设置新数据
let key = ref.child("posts").childByAutoId().key
let post = ["uid": userID,
"author": username,
"title": title,
"body": body]
let childUpdates = ["/posts/\(key)": post,
"/user-posts/\(userID)/\(key)/": post]
ref.updateChildValues(childUpdates)
消防处的答案
只需阅读Firestore的文档,使用 updateData 代替addDocument:
let washingtonRef = db.collection("cities").document("DC")
// Set the "capital" field of the city 'DC'
washingtonRef.updateData([
"capital": true
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("Document successfully updated")
}
}
设置/添加新数据
// Add a new document with a generated id.
var ref: DocumentReference? = nil
ref = db.collection("cities").addDocument(data: [
"name": "Tokyo",
"country": "Japan"
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
因此,经验法则是仅传递需要更新的字段,而不传递整个馆藏/词典。