You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase @DocumentID属性包装器失效,更新文档提示不存在

问题:Firestore文档更新失败 - 找不到指定文档

尝试更新Firebase中指定文档的特定值时,触发代码始终收到错误:

[FirebaseFirestore][I-FST000001] WriteStream (7fc6c510be38) Stream error: 'Not found: No document to update: projects/htg-inspection/databases/(default)/documents/Projects/365A2F53-CB38-47A6-93C3-7D6DA14038D9

错误显示要更新的文档ID不存在,当前数据结构体返回的是随机UUID而非Firestore中的实际文档ID。原本以为@DocumentID属性包装器能解决这个问题,怀疑是使用方式有误。


1. Projects数据结构体

import Foundation
import FirebaseFirestoreSwift
import FirebaseFirestore
import Firebase

struct ProjectsData: Identifiable, Codable{
    
    @DocumentID var id: String? = UUID().uuidString
    var title: String
    var client: String
    var description: String
    var inspections: [InspectionsData]

    enum CodingKeys: String, CodingKey{
        case id
        case title
        case client
        case description
        case inspections
    }
}

2. 子集合相关结构体

struct InspectionsData: Identifiable, Codable {
    
    var id = UUID()
    var category: Category
    var trade: String
    var inspectionDate: Date
    var dueDate: Date
    var assigned: Bool
    var location: String
    var images: [InspectionImages]
    var checklists: [ChecklistsData]
    
    var dateToString: String{
        let formatter = DateFormatter()
                formatter.dateFormat = "MMMM dd, YYYY "
                return formatter.string(from: inspectionDate)
    }

    var dueDateToString: String{
        let formatter = DateFormatter()
                formatter.dateFormat = "MMMM dd, YYYY "
                return formatter.string(from: dueDate)
    }
}

struct ChecklistsData: Identifiable, Codable{
    
    var id = UUID()
    var question: String
    var hasPassed: Bool
    var hasFailed: Bool
    var isnotApplicable: Bool
}

enum ChecklistCodingKeys: String, CodingKey{
    case id
    case question
    case hasPassed
    case hasFailed
    case isnotApplicable
}

3. 视图模型代码

class ProjectsViewModel: ObservableObject {
    
    @Published var projects = [ProjectsData]()
    @Published var inspectionData = [InspectionsData]()
    @Published var assignedProjects: [AssignedProjectsModel] = []
    @Published var retrievePhotos = [UIImage]()
    @Published var inspectionImages = [InspectionImages]()
    @Published var showImageViewer = false
    @Published var selectedImageID: String = ""
    @Published var checklists = [ChecklistsData]()
    @Published var hasPassed = false
    @Published var hasFailed = false
    @Published var isnotApplicable = false

    func updateChecklist(_ checklist: ProjectsData, hasPassed: Bool, hasFailed: Bool, isnotApplicable: Bool) {
        if let documentId = checklist.id {
            db.collection("Projects").document(documentId).updateData(["checklists" : ["hasPassed" : hasPassed, "hasFailed" : hasFailed, "isnotApplicable" : isnotApplicable]]) {
                error in
                
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("Document has been updated")
                }
            }
        }
    }
}

4. 发起更新的视图代码

struct ChecklistComponent: View {
    
    @State var hasPassed: Bool
    @State  var hasFailed: Bool
    @State  var isnotApplicable: Bool
    
    @ObservedObject var checklistvm = ProjectsViewModel()
    var documentID: ProjectsData

    var checklistItem: String = ""
    var question: String = ""
    
    var body: some View {
        VStack{
            HeaderOne(text: question, size: 16)
            
            Spacer()
            
            HStack{
                ChecklistButton(text: "Pass", textColor: hasPassed ? "#00AA97" : "#696969", buttonColor: hasPassed ? "#B0EFE8" : "#DBDBDB",
                                action: {
                    hasPassed.toggle()
                    hasFailed = false
                    isnotApplicable = false
                    checklistvm.updateChecklist(documentID, hasPassed: hasPassed, hasFailed: hasFailed, isnotApplicable: isnotApplicable)
                })
                
                ChecklistButton(text: "Fail", textColor: hasFailed ? "#AA0000" : "#696969", buttonColor: hasFailed ? "#EFB0B0" : "#DBDBDB",
                                action: {
                    hasFailed.toggle()
                    hasPassed = false
                    isnotApplicable = false
                    checklistvm.updateChecklist(documentID, hasPassed: hasPassed, hasFailed: hasFailed, isnotApplicable: isnotApplicable)
                })
                
                ChecklistButton(text: "N/A", textColor: isnotApplicable ? "#89AA00" : "#696969", buttonColor: isnotApplicable ? "#EDEFB0" : "#DBDBDB",
                                action: {
                    isnotApplicable.toggle()
                    hasFailed = false
                    hasPassed = false
                    checklistvm.updateChecklist(documentID, hasPassed: hasPassed, hasFailed: hasFailed, isnotApplicable: isnotApplicable)
                })
            }
        }
        .padding()
        .frame(width: UIScreen.main.bounds.width-30 ,height: 161)
        .background(.white)
        .cornerRadius(31)
    }
}

5. 使用@FirestoreQuery的视图代码

import SwiftUI
import Firebase
import FirebaseFirestore
import FirebaseFirestoreSwift

struct HomeView: View {
    
    @State var searchable = ""
    @State var navtoView = false
    @State var showLogoutdialog = false
    @ObservedObject var homevm = HomeViewModel()
    var auth = AuthService()
    @Environment(\.presentationMode) var presentationmode
    @State var firstname = ""
    @ObservedObject var projectvm = ProjectsViewModel()
    @State var selectedProject: ProjectsData?
    @FirestoreQuery(collectionPath: "Projects") var projects: [ProjectsData]
    
    var body: some View {
        NavigationView{
            ScrollView(.vertical){
                Spacer()
                    .height(70)
                HeaderComponent(firstname: users.firstName)
                
                SearchBar(searchText: $searchable)
                    .padding(.bottom)
                
                VStack {
                    ForEach(projects, id: \.id) { item in
                        ProjectFeedCard(projectTitle: item.title, client: item.client)
                            .onTapGesture {
                                self.selectedProject = item
                                navtoView.toggle()
                        }
                    }
                }
                
                //MARK: NavigationLinks
                NavigationLink(destination:ProjectView(inspections: selectedProject?.inspections ?? [], projectTitle: selectedProject?.title ?? "" , client: selectedProject?.client ?? "",description: selectedProject?.description ?? "", documentID: selectedProject ?? ProjectsData(title: "", client: "", description: "", inspections: []), checklists: []) , isActive: $navtoView){
                    EmptyView()
                }
                
                Spacer()
                
                CustomButton(action: {showLogoutdialog.toggle()}, buttonText: "Log Out", buttonColor: .accentColor)
                    .padding()
                 .confirmationDialog("Are you sure?", isPresented: $showLogoutdialog, titleVisibility: .visible){
                        Button("Sign Out", role: .destructive){
                            homevm.logOutApp()
                            presentationmode.wrappedValue.dismiss()
                        }
                    }
                 .onAppear{
                     projectvm.fetchProjects()
                 }
            }
            .background(Color(hexadecimal: "#F8F8F8"))
            .ignoresSafeArea()
            .navigationBarHidden(true)
        }
    }
}

内容的提问来源于stack exchange,提问作者Kevon Brown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 07:09:19