我在这样设置的文档中有一个值:
func uploadMedDosage(dosage: String, medication: String) {
let docRef = db.collection("users").document(userId!)
let updateData = ["medications" : [medication : dosage]]
docRef.setData(updateData, merge: true) { (err) in
if err != nil {
print(err?.localizedDescription as Any)
self.view.makeToast(err?.localizedDescription as! String)
} else {
self.refresh()
print(" Data Uploaded")
}
}
}
现在我需要删除此值,但是我不知道如何:
func removeMedDosage(dosage: String, medication: String) {
let docRef = db.collection("users").document(userId!)
let data = [[medication : dosage] : FieldValue.delete()]
docRef.updateData(["medications" : data]) { (err) in
print("delete")
}
}
这会编译但会导致崩溃:
由于未捕获的异常而终止应用程序 “ NSInvalidArgumentException”,原因: '-[__ TtGCs26_SwiftDeferredNSDictionarySSSS_ $长度]:无法识别 选择器发送到实例0x2830ca100'
我尝试了许多不同的变体,包括
let data = [[medication : dosage]]
docRef.updateData(["medications" : FieldValue.arrayRemove(data)]) { (err) in
print("delete")
}
Firestore中的数据设置如下:
medications {
Venlafaxine : 37.5,
Sertraline : 100
}
如何本质上删除[Venlafaxine:37.5]行。
答案 0 :(得分:0)
似乎没有办法用字典来做到这一点,只有一个数组。因此,我不得不删除整个部分,然后像这样重建它:
func removeMedDosage(dosage: String, medication: String) {
print("remove")
let docRef = db.collection("users").document(userId!)
removeDictionary = [:]
for (index, element) in self.meds.enumerated() {
removeDictionary[element] = self.dosages[index]
}
let data = removeDictionary
docRef.updateData(["medications" : data]) { (err) in
}
self.refresh()
}
为此,我从用于tableView的数组中删除了选定的一个:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "delete") { (action, indexPath) in
let index = indexPath.row
let med = self.meds[index]
let dose = self.dosages[index]
self.meds.remove(at: index)
self.dosages.remove(at: index)
self.tableView.deleteRows(at: [indexPath], with: .fade)
self.removeMedDosage(dosage: dose, medication: med)
}
return [delete]
}
答案 1 :(得分:0)
我知道您回答了自己的问题,但我想建议可能有一个更优雅的解决方案。
问题中缺少一些数据点,因此我将举一个示例案例-这可能在整个思考过程中有用。
让我们假设您的应用允许专利(用户)跟踪处方。这意味着将有多个用户,每个用户都有一个处方。那个处方有药物和剂量。
当用户想要删除处方时,代码将全部加载并迭代,直到找到正确的处方,然后将其删除。这就需要遍历真正效率低下的数据。
让我们提出另一种方法,我们假定这是针对用户0(uid_0)
这是Firestore结构的外观
user_prescriptions
uid_0
prescriptions
prescription_0
medication: "some med"
dosage: "some dosage"
prescription_1
medication: "some med"
dosage: "some dosage"
uid_1
prescriptions
prescription_0
medication: "some med"
dosage: "some dosage"
prescription_1
medication: "some med"
dosage: "some dosage"
当用户想要添加药物时,我们调用函数 uploadPrescription 并将其传递给药方和剂量
self.uploadPrescription(dosage: "100mg", medication: "Aspirin")
这是将数据写入Firestore的功能。
func uploadPrescription(dosage: String, medication: String) {
let uid = "uid_0"
let collectionRef = db.collection("users_prescriptions").document(uid).collection("prescriptions")
let prescriptionData = ["medication": medication,
"dosage": dosage]
var ref: DocumentReference? = nil
ref = collectionRef.addDocument(data: prescriptionData) { err in
if let err = err {
print(err.localizedDescription)
return
} else {
let docJustAddedRef = ref?.documentID
print(docJustAddedRef!)
//maybe create a PrescriptionClass and add it to a tableview
}
}
}
值得注意的是,此函数为每个处方创建一个唯一的子节点并捕获对其的引用(这是piquot_0和discription_1 id的来源)。
该引用将具有一个documentID。这将使每个用户都有无限数量的独特处方。
然后,处方信息可以显示在UI中的tableView中。 documentID是该特定处方的标识符,从那时起将用于删除或更改处方信息。在应用启动时,很多时候,所有的处方都会被加载到一个类中,并且每个处方都将存储在用作tableView数据源的数组中。当用户滑动以删除时,您将得到他们想要删除的行,从数组中获取该处方对象-从数组中删除它,然后使用documentID从Firestore中删除它。
func removeMedDosage(documentID: String) {
let uid = "uid_0"
let docRef = db.collection("users_scripts").document(uid).collection("prescriptions").document(documentID)
docRef.delete()
}