Samuel Lubrano
Samuel Lubrano

Reputation: 47

How to get an object in Firestore (iOS)

How do you get an object in Firestore by its id in Swift? I would then need to use this object to generate content in the UI. I am using SwiftUI. The object I am trying to get is a user and it has the following structure:

struct AppUser: Codable {

    var id: String
    var displayName: String
    var photoURL: String
    var points: Int
    var knownLanguageCodes: Set<String>

}

The each document in the "users" collection has the fields in the AppUser struct. Ideally, I would like to write a function that returns an AppUser object from Firestore:

func getUser(withId id: String) -> AppUser {
    //I don't know how to write this function
}

The object would then be used like this:

struct ProfileHeadingView: View {

    let userId: String
    let user = getUser(withId: userId)

    var body: some View {
        HStack {
            ImageView(withURL: self.user.photoURL)
                .frame(width: 90, height: 90)
                .clipShape(Circle())
            VStack (alignment: .leading) {
                Text(self.user.displayName)
                    .font(.largeTitle)
                    .fontWeight(.heavy)
                HStack {
                    Text(String(self.user.points))
                        .font(.title)
                    Spacer()
                }
            }.padding(.horizontal)
        }
    }
}

Upvotes: 1

Views: 305

Answers (1)

Peter Friese
Peter Friese

Reputation: 7254

Most of Firebase's APIs are asynchronous - this is due to the fact that most of them involve a network call, which is much slower than code gets executed on your phone!

So, your getUser method would need to be rewritten like this:

import FirebaseFirestoreSwift

func getUser(userId: String, completion: @escaping (_ user: AppUser?, _ error: Error?) -> Void) {
  db.collection("users").document(userId).getDocument { (snapshot, error) in
    let user = try? snapshot?.data(as: AppUser.self)
    completion(user, error)
  }
}

Note: to be able to use Firestore's Codable support, you will have to add pod 'FirebaseFirestoreSwift' to your Podfile

As for how (and when) to fetch the user, this largely depends on whether ProfileHeadingView is part of a list view (or is being navigated to from a list view), or not.

If it is part of a list view, I'd recommend fetching all users at once - you can either use a snapshot listener to listen for any updates to the users collection, or perform a one-time fetch to read the users collection once.

Then, from the list view, pass the respective user object into the ProfileHeadingView.

Upvotes: 1

Related Questions