簡體   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