Mapping Firestore documents using Swift Codable

Firebase · 21K views · 2020 · 14:28

Open on YouTube

Web developmentSoftware (other)tutorialdated

Why Stack Overflow recommends it

Stack Overflow users link it when answering questions about turning Firestore snapshots into typed Swift structs instead of handling [String: Any] dictionaries by hand.

Recommended by 4 people across 4 different months, 2020 to 2023.

What it is

A 14-minute Firebase Semi-live episode in which Peter Friese shows how to map Cloud Firestore documents to Swift structs using the Codable API and the FirebaseFirestoreSwift pod. It covers making a model Codable, mapping the document ID, refactoring a SwiftUI view model, writing data back, and the @ServerTimestamp and @ExplicitNull property wrappers.

What people said

Recommends Dim Novo · 2020-08 · Stack Overflow · on “Im trying to save custom data to cloud firestore in swiftUI, Im trying to construct the data i get from snapshot listener”

There is no need to create a class for your data structure . A Class: ObservableObject accepts, processes, and passes (published) needed data(values) to your View according to your data structure ... A good news: Firebase supports the Swift Codable Protocol – check this link [this video]

Recommends Peter Friese · 2020-09 · Stack Overflow · on “Fetching data from collection 'profiles' in Cloud Firestore with SwiftUI. Cannot assign value of type '[String : Any]' to type 'UserProfile'”

Firebase supports the Codable API, which enables you to perform type-safe mapping from Firebase documents to Swift structs. Here's what you need to do to implement it: Add FirebaseFirestoreSwift to your Podfile Import FirebaseFirestoreSwift Make sure your UserProfile struct implements Codable When reading documents, you can call return try? queryDocumentSnapshot.data(as: UserProfile.self) When writing documents, call try db.collection("profiles").addDocument(from: userProfile) I covered this in detail in Mapping Firestore Data in Swift - The Comprehensive Guide [LINK] , and also recorded this video [this video] .

Recommends bze12 · 2021-09 · Stack Overflow · on “Firebase Firestore for Swift doesn't seem to be reaching Google Cloud”

i know it's not related to your original question, but there's no need to use the toArray() method to serialize your struct into data for firestore. You can just make your struct adopt the Codable protocol. see [this video]

Recommends Michael · 2022-04 · Stack Overflow · on “Convert Firestore Data into own Array format”

You can create a struct called BusinessCategories for storing each of the category item, within your project. You will need to use Codable Protocols and use setData function (write function) to create necessary documents in the Firestore. struct BusinessCategories: Codable, Identificable { var id: String var name: String var image: String enum CodingKeys: String, CodingKey { case id case name case image } } After storing data model BusinessCategories in the Firestore, you can retrieve them via getDocuments or snapshotlisteners whichever you prefer. Once you retrieve/read the BusinessCategories document From Firestore, you can decode (use for-loop to convert document into the struct you alrea

Cites Peter Friese · 2020-06 · Stack Overflow · on “Firebase+SwiftUI. Cannot convert value”

The data() method returns a dictionary that maps form String to Any - see this video [this video] for a detailed explanation. Looking at your data model [LINK] , I noticed that you've got an id field on all documents that is equivalent to the document ID. This is actually not required, as you can use the document ID directly: let id = queryDocumentSnapshot.documentID However, I'd recommend using Firestore's Codable support to make this even easier: let routine = try? queryDocumentSnapshot.data(as: Routine.self) To make this work, you'll need to add the FirebaseFirestoreSwift , and make your model Codable . Read more about this in this SO answer [LINK] , and this [LINK] and this article [LINK] , r

Cites Mateus Neves · 2020-12 · Stack Overflow · on “Type '' does not conform to protocol 'Decodable'/'Encodable'”

I have this code to get information from firestore: struct Spty: Identifiable, Codable{ @DocumentID var id: String? = UUID().uuidString var spty: String var r: NSNumber var g: NSNumber var b: NSNumber } class SptyViewModel: NSObject, ObservableObject{ @Published var specialities = [Spty]() @Published var search = "" func fetchData(){ let db = Firestore.firestore() db.collection("specialities").addSnapshotListener { (querySnapshot, error) in guard let documents = querySnapshot else {return } self.specialities = documents.documents.compactMap { (doc) -> Spty? in let id = doc.documentID if let spty = doc.get("spty") as? String, let r = doc.get("r") as? NSNumber, let g = doc.get("g") as? NSNumbe

Cites fortniteplayer51943 · 2022-02 · Stack Overflow · on “How can I properly read/write a users cart items document in firebase firestore on iOS?”

class CartViewModel: ObservableObject { @Published var cartItems = [Cart]() @Published var errorMessage = "" private var db = Firestore.firestore() func fetchData() { db.collection("customers").document(Auth.auth().currentUser!.uid).collection("cart").addSnapshotListener{(querySnapshot, error) in guard let documents = querySnapshot?.documents else { print("no documents") return } self.cartItems = documents.compactMap { (queryDocumentSnapshot) -> Cart? in return try? queryDocumentSnapshot.data(as: Cart.self) } if let error = error { self.errorMessage = error.localizedDescription return } } }} struct Cart: Identifiable, Codable { let db = Firestore.firestore() @DocumentID var id: String? var n

Cites Rohit Kharche · 2023-04 · Stack Overflow · on “How to properly reference an auto generated Cloud Firestore Document id?”

You can use swift’s Codable [LINK] it’s a type alias for the Encodable and Decodable protocols. By conforming a Swift type to this protocol, the compiler will synthesize the code needed to encode/decode an instance of this type from a serialized format, such as JSON. With codable your struct will become : import FirebaseFirestoreSwift struct Service: Codable { @DocumentID var id: String? var name: String var price: Double } Using codable will help you transform your firestore document into strictly typed struct and after implementing this change you also need to update your updateService method as follows: @MainActor func updateService(service: Service) async throws { let db = Firestore.fire