Firestore中Date类型数据提取与计算问题求助
问题:从Firestore获取的Date类型数据提取失败
背景信息
从Firestore获取startDate(Date类型)数据后,能在List视图中正常展示,但无法提取单个Date值赋值给变量用于计算,报错:
Error: Cannot convert return expression of type '[dateSetting]' to return type 'Date'
相关代码
Firestore数据结构
struct dateSetting: Identifiable, Equatable, Codable, Hashable { var id = UUID() var startDate: Date }
数据获取代码
func fetchPosts() async throws -> [dateSetting] { guard let uid = Auth.auth().currentUser?.uid else { return [] } let snapshot = try await startDateReference1.document(uid).collection("startDate") .order(by: "startDate", descending: true) .getDocuments() return snapshot.documents.compactMap { document in try! document.data(as: dateSetting.self) } }
ViewModel代码
@Published var startDateData: Loadable<[dateSetting]> = .loading ... func fetchDatePosts() { Task { do { startDateData = .loaded( try await startDateRepository.fetchPosts()) print(startDate) } catch { print("[TravelStartDateViewModel] Cannot fetch posts: \(error)") } } }
打印结果
loaded([Days_Checker.dateSetting(id: 99F73F53-C527-4D8E-8D2A-F3D227CE1F5E, startDate: 2023-05-04 13:30:00 +0000)])
可正常工作的视图展示代码
List(viewModel.startDateData) { date in DateRowsView(startDate: date) ...
struct DateRowsView: View { let startDate: dateSetting var body: some View { VStack(alignment: .leading) { Text(dateFormatter.string(from: startDate.startDate)) ...
对比:可正常处理的typeSetting代码
func fetchTheTypePosts() { Task { do { let fetchedType = try await typeRepository.fetchPosts() theType = calculateType(ty: fetchedType) print("theType: " + theType) } catch { print("[TravelTypeViewModel] Cannot fetch posts: \(error)") type = .error(error) } } } func calculateType(ty: [typeSetting]) -> String { let totalType = ty.reduce("") { $0 + $1.type } return totalType }
解决方案
核心问题:fetchPosts()返回的是数组类型[dateSetting],而你需要的是单个Date值,必须先从数组中拿到对应的dateSetting元素,再访问其startDate属性。
场景1:取数组第一个元素的startDate(适合按降序排序后取最新数据)
func fetchDatePosts() { Task { do { let fetchedDates = try await startDateRepository.fetchPosts() startDateData = .loaded(fetchedDates) // 提取第一个元素的startDate,先判断数组非空 if let firstDateItem = fetchedDates.first { theStartDate = firstDateItem.startDate print("提取到的startDate: \(theStartDate)") } else { print("未获取到任何日期数据") } } catch { print("[TravelStartDateViewModel] Cannot fetch posts: \(error)") } } }
场景2:处理数组中所有startDate(如计算最早/最晚日期)
// 自定义计算逻辑:获取最早的startDate func calculateEarliestStartDate(from dateItems: [dateSetting]) -> Date? { return dateItems.map { $0.startDate }.min() } // 在fetch方法中调用 func fetchDatePosts() { Task { do { let fetchedDates = try await startDateRepository.fetchPosts() startDateData = .loaded(fetchedDates) if let earliestDate = calculateEarliestStartDate(from: fetchedDates) { theStartDate = earliestDate print("最早的日期: \(earliestDate)") } } catch { print("[TravelStartDateViewModel] Cannot fetch posts: \(error)") } } }
场景3:从已加载的startDateData中提取
如果需要在startDateData状态更新后处理,可以通过模式匹配提取数组:
// 示例:在ViewModel的其他方法或视图回调中使用 if case .loaded(let dateItems) = startDateData { if let targetDate = dateItems.first?.startDate { theStartDate = targetDate } }
内容的提问来源于stack exchange,提问作者Mech
相关产品推荐
相关产品推荐

