繁体   English   中英

'无效的文档参考。 尝试编辑/删除新条目时,文档引用必须具有偶数段

[英]'Invalid document reference. Document references must have an even number of segments' when trying to edit/delete new entry

首次加载我的应用程序时,我可以删除登录的用户文档。 但是,如果我创建一个新条目,长按表格视图中的新条目并删除 select,我会崩溃。 我认为这与未保存文档 ID 有关,但我不知道为什么。 如果在关闭并重新打开应用程序后删除相同的新创建条目,那么它将毫无问题地删除,但如果我在创建新文档后立即打开应用程序并删除,它将崩溃。 火库

class BudgetViewController: UIViewController: {


     var budgetData = [Transaction]()
     func showAdd() {
     
        let modalViewController = AddCategory()
        modalViewController.addCategoryCompletion = { newCategories in
            self.budgetData.append(newCategories)
            self.tableView.reloadData()
        }
            modalViewController.modalPresentationStyle = .overFullScreen
        modalViewController.modalTransitionStyle = .crossDissolve
             modalViewController.selectionDelegate = self
             present(modalViewController, animated: true, completion: nil)
    }

     @objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer){
        if gestureRecognizer.state == .began {
            let touchPoint = gestureRecognizer.location(in: self.tableView)
            if let indexPath = tableView.indexPathForRow(at: touchPoint) {
                let cell = CategoryCell()
                var data = budgetData[indexPath.row]
           
                let modalViewController = EditCategory()
                modalViewController.deleteCategory = { row in
                    self.deletedRow = row
                    self.deleteRow()
                }
                modalViewController.documentID = data.trailingSubText ?? ""
                modalViewController.modalPresentationStyle = .overFullScreen
            modalViewController.modalTransitionStyle = .crossDissolve
                 present(modalViewController, animated: true, completion: nil)

                modalViewController.row = indexPath.row
                print("longpressed\(indexPath.row)\(data.trailingSubText)")
               
            }
        }
    }
       override func viewDidLoad() {
        loadNewData()
    }
      func loadNewData() {
        guard let user = Auth.auth().currentUser?.uid else { return }
        db.collection("users").document(user).collection("Category").getDocuments() {
                snapshot, error in
                if let error = error {
                    print("\(error.localizedDescription)")
                } else {
                    for document in snapshot!.documents {

                        let data = document.data()
                        let title = data["title"] as? String ?? ""
                        let uid = data["uid"] as? String ?? ""
                        let documentID = document.documentID
                   //     let timeStamp = data["timeStamp"] as? Date

                        let newSourse = Transaction(title: title, dateInfo: "0% out of spent", image: UIImage.gymIcon, amount: 12, annualPercentageRate: 12, trailingSubText: documentID, uid: uid)
                        self.budgetData.append(newSourse)
                    }
                    self.tableView.reloadData()
                    
                }
            }
        }

     class AddCategory: UIViewController {
        @objc func saveAction(){
      
        guard let uid = Auth.auth().currentUser?.uid else { return }

        let newCategory = Transaction(title: textField.text ?? "", dateInfo: "0% out of spent", image: UIImage.gymIcon, amount: 12, annualPercentageRate: 23, trailingSubText: "", uid: uid)
       
        
       db.collection("users").document(uid).collection("Category").addDocument(data: newCategory.dictionary)

        self.dismiss(animated: false, completion: {
                    self.addCategoryCompletion?(newCategory)
        })
        self.dismiss(animated: false, completion: nil)
        print("selected")
   
       }
      }
     }

       class EditCategory: UIViewController {
    func deleteAction(){
        guard let user = Auth.auth().currentUser?.uid else { return }

        print("document::\(self.documentID)")
      //  let budget = textField.text
        
        db.collection("users").document(user).collection("Category").document(documentID).delete { (err) in
            if let err = err {
                print(err.localizedDescription)
            }else{
                
                self.dismiss(animated: false, completion: {
                    self.deleteCategory?(self.row)
                })
                
                print("deleted successfully")
            }
        }
        
    }
}

该错误强烈表明在您运行此代码时user为 nil 或为空:

guard let user = Auth.auth().currentUser?.uid else { return }
db.collection("users").document(user).collection("Category").getDocuments() 

这几乎可以肯定意味着用户当时没有登录。 在尝试访问其 uid 属性之前,您的代码需要检查currentUser是否为 nil。 nil 表示当前没有用户登录。

用户不会在应用启动时立即登录。 当用户 object 可用时,您应该使用 auth state 侦听器来获取回调。

也许不是最好的方法,但它现在正在工作。 我打了电话

    self.budgetData.removeAll()
    self.loadNewData()
    self.tableView.reloadData()

在我的回调中

        modalViewController.addCategoryCompletion = { newCategories in
        self.budgetData.append(newCategories)
        self.tableView.reloadData()
    }`

根据提供的代码,当向 Firebase 添加新类别时

let newCategory = Transaction(title: textField.text ?? ...)
db.collection("users").document(uid).collection("Category").addDocument(data: newCategory

您首先没有从 Firebase 获得有效的 documentId。 因此,object 存在于您的数据源中,没有 documentId,因此当您尝试删除它时,会发生崩溃。

几个选项

选项 1:首先创建一个 firebase 引用,它将提供一个 Firebase 文档 ID,您可以在编写时将其添加到 object 中。 请参阅文档 像这样

let newCategoryRef = db.collection("Category").document()
let docId = newCategoryRef.documentId
...add docId to the category object, then add to dataSource

或者

选项 2:向节点添加观察者(请参阅实时更新),因此当写入新文档时,观察者事件将触发并显示新添加的文档,其中将包含有效的 documentId,然后根据该文档制作类别 object数据并将 object 添加到您的数据源数组中。 在这种情况下,您不需要在写入时将其添加到 dataSource 数组中,因为它会在写入后根据observers.added 事件自动添加。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM