Swift中Firestore数据存储与更新问题:setData与updateData用法
嘿,我太懂你这个头疼的问题了——每次想往字典里加新URL,结果把之前存的内容全覆盖了,对吧?刚接触Firestore的时候我也踩过这个坑,来给你把setData和updateData的用法掰扯清楚,顺便搞定逐个加URL的需求。
先搞懂核心区别:setData vs updateData
敲黑板!这俩方法的本质差异直接决定了你的数据会不会被覆盖:
setData:默认是「替换整个文档」——如果文档不存在就创建新的,存在的话就把原有内容全换成你传的新数据。除非你加merge: true参数,它才会变成「只更新你指定的字段,保留其他已有内容」。updateData:专门用来「更新文档里的特定字段」,完全不会碰其他字段,但有个前提:文档必须已经存在,不然会报错。
正确实现:逐个添加URL到字典的两种场景
假设你存在Firestore里的字段是个叫faceUrls的字典,key是faceRef.documentID,value是图片的下载URL,分两种情况处理:
场景1:用户文档已经存在,只需要往字典加新条目
用updateData就最适合了,配合Firestore的点符号语法,直接给字典追加新的key-value对,完全不会覆盖原有内容:
// 先拿到你的文档引用,比如fsReference.document("users/\(currentUser.value!.documentID)") let db = self.fsReference.document("users/\(currentUser.value!.documentID)") let urlKey = faceRef.documentID let updateDict: [String: Any] = [ "faceUrls.\(urlKey)": downloadURL ] db.updateData(updateDict) { error in if let err = error { print("更新失败:\(err.localizedDescription)") } else { print("新URL成功加到字典里啦!") } }
这里的faceUrls.\(urlKey)相当于告诉Firestore:找到faceUrls这个字典,给它新增一个key为urlKey、值为downloadURL的条目,原有的条目一概不动。
场景2:用户文档可能还没创建(第一次添加URL)
这时候用setData加merge: true参数,既能自动创建文档(如果不存在),又能只更新指定字段,不会覆盖后续加的内容:
let db = self.fsReference.document("users/\(currentUser.value!.documentID)") let urlKey = faceRef.documentID let setDict: [String: Any] = [ "faceUrls.\(urlKey)": downloadURL ] db.setData(setDict, merge: true) { error in if let err = error { print("设置/更新失败:\(err.localizedDescription)") } else { print("URL添加成功,文档不存在的话已经自动创建啦!") } }
你之前踩坑的原因
估计你之前是直接把整个faceUrls字典传进setData里了,比如setData(["faceUrls": [urlKey: downloadURL]])——这就等于告诉Firestore:把faceUrls字段完全替换成你传的这个只有新条目的字典,原有内容自然就没了。而用点符号或者updateData就能完美避开这个问题。
内容的提问来源于stack exchange,提问作者Max Kraev
相关产品推荐
相关产品推荐

