mintyfree
mintyfree

Reputation: 23

Unable to retrieve timestamp data on Firebase to SwiftUI

I've been trying to retrieve my timestamp data on Firebase to SwiftUI but keep running into an error: Could not cast value of type 'FIRTimestamp' (0x107db0b88) to 'FIRTimestamp' (0x10d78ec58)

This is very peculiar to me as it seems that Swift is unable to unwrap my timestamp data though it is of the right type.

This is a snippet of my code that ran into trouble:

for i in query!.documentChanges {
  let dateOfConsumption = i.document.get("date of consumption") as! Timestamp 

Upvotes: 0

Views: 938

Answers (1)

Peter Friese
Peter Friese

Reputation: 7254

I'd recommend using FirebaseFirestoreSwift so you can use Codable to map your documents to Swift structs, like this:

Your Podfile:

platform :ios, '13.0'

target 'MakeItSo' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MakeItSo
  
  pod 'Firebase/Analytics'
  pod 'Firebase/Firestore'
  pod 'FirebaseFirestoreSwift'
end

Your model:

import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift

enum TaskPriority: Int, Codable {
  case high
  case medium
  case low
}

struct Task: Codable, Identifiable {
  @DocumentID var id: String?
  var title: String
  var priority: TaskPriority
  var completed: Bool
  @ServerTimestamp var createdTime: Timestamp?
  var userId: String?
}

Your view model:

class FirestoreTaskViewModel:  ObservableObject {
  var db = Firestore.firestore()

  var tasksPath: String = "tasks"
  var userId: String = "unknown"
  
  private var listenerRegistration: ListenerRegistration?
  private var cancellables = Set<AnyCancellable>()
  
  func loadData() {
    if listenerRegistration != nil {
      listenerRegistration?.remove()
    }
    listenerRegistration = db.collection(tasksPath)
      .whereField("userId", isEqualTo: self.userId)
      .order(by: "createdTime")
      .addSnapshotListener { (querySnapshot, error) in
        if let querySnapshot = querySnapshot {
          self.tasks = querySnapshot.documents.compactMap { document -> Task? in
            try? document.data(as: Task.self)
          }
        }
      }
  }

This will automatically map your timestamps.

See Connecting SwiftUI and Cloud Firestore for an in-depth walkthrough of how to build a SwiftUI application that fetches data from Cloud Firestore, and Mapping Firestore Documents using Swift Codable for how to use Codable with Firestore.

Upvotes: 1

Related Questions