【问题标题】:Firestore iOS - Delete function in UITableviewFirestore iOS - UITableview 中的删除功能
【发布时间】:2018-06-14 23:14:16
【问题描述】:

我正在尝试使用滑动删除功能从 Firestore 中删除一个在我的 UITableView 上显示为 UITableViewCell 的文档。

 var sourseArray : [Sourse] = []

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let sourseItem = sourseArray[indexPath.row]
        Firestore.firestore().collection("sourses").document(sourseItem.documentId).delete(completion: { (error) in
            if let error = error {
                debugPrint("Could not delete thought: \(error.localizedDescription)")
            }
        })
    }
}

当我滑动并点击“删除”按钮时。出现这个错误

*** 由于未捕获的异常“FIRInvalidArgumentException”而终止应用程序,原因:“无效的文档引用。 文档引用必须有偶数个段,但源 有 1'

我调整了 Firestore 数据库的“规则”以允许删除。

经过一些研究,我似乎没有以某种方式引用正确的文档。它是一个错误的参考还是其他错误?

这也是“源”模型的含义。

class Sourse {
    private(set) var name: String!
    private(set) var content: String!
    private(set) var timeStamp: Date!
    private(set) var documentId: String!
    private(set) var userId: String!

    init(name: String, timeStamp: Date, content: String, documentId: String, userId: String) {
        self.name = name
        self.content = content
        self.timeStamp = timeStamp
        self.documentId = documentId
        self.userId = userId
    }
}

//编辑

我刚刚注意到在创建新源时我没有添加 documentId。如下所示。

@IBAction func addSourse(_ sender: Any) {
        Firestore.firestore().collection(SOURSES_REF).addDocument(data: [
            NAME : sourseTextField.text ?? "",
            CONTENT : contentTextField.text ?? "",
            TIMESTAMP : FieldValue.serverTimestamp(),
            USERNAME : Auth.auth().currentUser?.displayName ?? "",
            USER_ID : Auth.auth().currentUser?.uid ?? ""

        ]) { (err) in
            if let err = err {
                debugPrint("Error adding document document: \(err)")
            } else {
                self.navigationController?.popViewController(animated: true)
            }
        }
    }

但是,这也是我的教程中的方式,并且效果很好。

///Edit 2 显示我是如何获取它的。

 func loadData() {
        db.collection("sourses").getDocuments() { (snapshot, error) in
            if let error = error {
                print(error.localizedDescription)
            } else {
                if let snapshot = snapshot {
                    for document in snapshot.documents {
                        let data = document.data()
                        let name = data["name"] as? String ?? ""
                        let content = data["content"] as? String ?? ""
                        let timeStamp = data["timeStamp"] as? Date ?? Date()
                        let documentId = data["documentId"] as? String ?? ""
                        let userId = data["userId"] as? String ?? ""
                        let newSourse = Sourse(name:name, timeStamp: timeStamp, content:content, documentId: documentId, userId: userId)
                        self.sourseArray.append(newSourse)

                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    }

Answer: 滑动删除功能一直都是正确的。正如 Dopapp 指出的那样,我错误地加载了我的 document.Id。

【问题讨论】:

  • sourseItem.documentId 的值是多少?
  • 它是源模型的一部分。根据我的阅读,您假设使用 documentID 进行删除。但是是的,该字段在我的 Firestore 数据库中为空,而其他所有字段都已填充。在我遵循的教程中,它的工作方式相同。
  • 我用它来引用必须删除的“源”....我希望
  • 你能在 let sourseItem = sourseArray[indexPath.row] 之后添加 print(sourseItem),运行应用程序并复制从控制台在您的问题中包含该文本?
  • 刚试过。它给了我同样的错误,“由于未捕获的异常'FIRInvalidArgumentException'而终止应用程序,原因:'无效的文档引用。文档引用必须有偶数个段,但源有 1'”

标签: ios swift uitableview firebase google-cloud-firestore


【解决方案1】:

如果问题确实是您的documentId 错误,则您可能检索不正确。下面是一个快速示例,说明如何使用正确的 id 创建对象:

collection.addSnapshotListener { (snapshot, error) in
    if let documents = snapshot?.documents {
        for document in documents {
            guard let data = document.data() else { continue }
            let id = document.documentID
            let sourseItem = Sourse(name: data['name'], ...,  documentId: id, ...)
            // use sourseItem
        }
    }
}

如果您正在做类似的事情,我会检查文档 ID 是否在对象之间交换。如果是这样,这可能表明存在与异步相关的问题。

对于您的特定情况,loadData() 应如下所示:

func loadData() {
    db.collection("sourses").getDocuments() { (snapshot, error) in
        if let error = error {
            print(error.localizedDescription)
        } else {
            if let snapshot = snapshot {
                for document in snapshot.documents {
                    let data = document.data()
                    let name = data["name"] as? String ?? ""
                    let content = data["content"] as? String ?? ""
                    let timeStamp = data["timeStamp"] as? Date ?? Date()
                    let documentId = document.documentID
                    let userId = data["userId"] as? String ?? ""
                    let newSourse = Sourse(name:name, timeStamp: timeStamp, content:content, documentId: documentId, userId: userId)
                    self.sourseArray.append(newSourse)

                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-09
    • 2018-12-09
    • 2021-02-13
    • 2018-04-23
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 2012-12-23
    相关资源
    最近更新 更多