DocumentId wrapper is not working properly

Viewed 603

I am using @DocumentId in my data struct:

struct UserProfile : Codable, Identifiable {
    @DocumentID var id: String? = UUID().uuidString
}

When I try to access the id I get a random string of letters (04F9C67E-C4A5-4870-9C22-F52C7F543AA5) Instead of the name of the document in firestore (GeG23o4GNJt5CrKEf3RS)

To access the documentId I am using the following code in an ObservableObject:

    class Authenticator: ObservableObject {
        
        @Published var currentUser: UserProfile = UserProfile()
        @Published var user: String = ""    
    
        func getCurrentUser(viewModel: UsersViewModel) -> String {
            guard let userID = Auth.auth().currentUser?.uid else {
                return ""
            }
            
            viewModel.users.forEach { i in
                if (i.userId == userID) {
                    currentUser = i
                }
            }
                    
            print("userId \(currentUser.id ?? "no Id")")
            print("name \(currentUser.name)")
            
            return userID
        }

Where currentUser is a UserProfile struct. currentUser.name returns the proper value. What am I doing wrong?

currentUser is a member of an array populated using the following method:

func fetchData() {
    db.collection("Users").addSnapshotListener { (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else {
            print("No documents")
            return
        }
        
        self.users = documents.compactMap { (queryDocumentSnapshot) -> UserProfile? in
            
            return try? queryDocumentSnapshot.data(as: UserProfile.self)
        }
    }
}
3 Answers

The id of the UserProfile struct and the id of your data in Firestore are separate. That's why you're seeing the random string of letters.

I would change your struct similar to the below and you can just ignore the regular "id" variable when you initialize and refer to the documentID instead.

struct UserProfile : Codable, Identifiable {
    var id = UUID() // ID for the struct
    var documentID: String // ID for the post in Database
}

The problem is that you're overwriting the fetched DocumentID with a newly generated UUID string. You should keep it uninitialized, there is no need to set an ID manually. Even if there is, then you should set it only if the object is created from code but not if it gets decoded from Firestore

found my specific problem, I defined CodingKeys enum and when you do that, you have to make sure that you have a mapping for every attribute.

make sure you put all of your model attributes in CodingKeys enum or don't use custom CodingKeys at all

EDIT: taking the above back...it's still buggy...maybe decodes fine but not encodes and uploading

my workaround for now is to not use .adddocument but instead .setdataenter image description here

Related