Search code examples
swiftdictionarygoogle-cloud-firestorecore-datacasting

Swift - Working with data returned from Firestore fetching


I have a CoreData object called FavoriteArticle. I store it in Firestore as a collection of objects for each user I have.

This is my CoreData: my CoreData entity of FavoriteArticle

This is my Firestore: my Firestore hierarchy

When I try to fetch the savedArticles of the currentUser I encounter an issue that I can't figure out how to solve:

The data that returns is of type [String:Any] while I need it to be [String:FavoriteArticle] to pass it to the completionHandler and use it later on in my app. I cannot user Firebase's custom objects code because CoreData does not conform to the Codable.

This is my current poor attempt of a workaround but my app keeps crushing on the line of favoriteArticle.title = "\(document.data()["title"])" with the error Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FavoriteArticle setTitle:]: unrecognized selector sent to instance 0x6000022ca840' -

func fetchUserDataCollection(uid: String, completionHandler: @escaping(String?,[String : FavoriteArticle]?) -> ()) {
    
    let docRef = database.collection("Users").document(uid).collection("savedArticles")
    docRef.getDocuments { (querySnapshot, error) in
        if let error = error {
            completionHandler("Error getting documents: \(error)",nil)
        } else {
            var resultsDictionary: [String: FavoriteArticle] = [:]
            for document in querySnapshot!.documents {
                let favoriteArticle = FavoriteArticle()
                print(document.data()["title"] as! String)
                favoriteArticle.title = "\(document.data()["title"])"
                favoriteArticle.isFavorite = (document.data()["isFavorite"] as? Bool)!
                favoriteArticle.author = document.data()["author"] as! String
                favoriteArticle.topic = document.data()["topic"] as! String
                favoriteArticle.imageUrl = document.data()["imageUrl"] as! String
                favoriteArticle.content = document.data()["content"] as! String
                favoriteArticle.url = document.data()["url"] as! String
                favoriteArticle.date = document.data()["date"] as! String
                
                resultsDictionary[document.documentID] = favoriteArticle
            }
            completionHandler(nil,resultsDictionary)
        }
    }
}

How can I solve this?


Solution

  • Issue was with the line let favoriteArticle = FavoriteArticle() because I forgot to add the context inside it. Changing to:

    let favoriteArticle = FavoriteArticle(context: (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext)
    

    fixed the issue