firebasegoogle-cloud-firestoreswiftuimultidatepicker

Swift Multidatepicker doesn't recognize dates loaded from Firebase


I have an issue where when dates are loaded from firebase into my MultiDatePicker, the onChange function does not recognize dates that are already in the "selectedDates" array, instead re-adding them to the array. I.e. if I have loaded July 19th into the multidatePicker, it displays on the calendar, but clicking it doesn't remove July 19th from the "selectedDates array". This is the code for the view:

        VStack {
            MultiDatePicker("Select dates", selection: $selectedDates)
                .padding()
                .onChange(of: selectedDates) { oldValue, newValue in
                    saveDates(dates: selectedDates)
                 }
            List(savedDates, id: \.self) { date in
                Text("\(date, formatter: dateFormatter)")
            }
            .listStyle(.plain)
        }
        .onAppear {
            loadSavedDates()
        }

Where selectedDates is a state variable:

@State var selectedDates: Set<DateComponents> = []

If nothing is on Firebase, the selection and deselection of dates happens fine, but if I am loading dates from firebase then the multidatepicker doesn't detect de-selection of dates. Here's my code for loading the dates from firebase:

func loadSavedDates() {
        let db = Firestore.firestore()
        let uid = try! AuthenticationManager.shared.getAuthenticatedUser().uid
        print("User ID: \(uid)")
        print(widget.id.uuidString)
        
        db.collection("spaces")
            .document(spaceId)
            .collection("dates")
            .document(widget.id.uuidString)//widget.id.uuidString
            .getDocument {document, error in
                if let document = document {
                    if let dateStrings = document.data()?[uid] as? [String] {
                        let dateFormatter = DateFormatter()
                        dateFormatter.dateStyle = .medium
                        self.savedDates = dateStrings.compactMap { dateFormatter.date(from: $0) }.sorted()
                        let calendar = Calendar.current
                        self.selectedDates = Set(self.savedDates.map { calendar.dateComponents([.year, .month, .day], from: $0) })
                        for component in selectedDates {
                            print(component.isValidDate)
                        }
                    }
                } else {
                    print("Document does not exist")
                }
            }

This is an example of terminal output after dates are loaded and I select "July 24th" in the multidatepicker:enter image description here, in the first line it prints the loaded the array of dates, and in the second line after I press July 24th on the multidatepicker it just adds it to the array again instead of removing it.

As you can see, I believe I am setting the selectedDates array correctly with datecomponents. Is there a problem with my code or is there just no way to pass dates from Firebase into multidatepicker?


Solution

  • Use [.calendar, .era, .year, .month, .day] instead of [.year, .month, .day] because that is the DateComponents format MultiDatePicker expects. Then selection will work correctly.