0

I have a project in swift with Firestore for the database. My firestore dataset of a user looks like this. User details with an array that contains objects.

enter image description here

I have a function that gets the specifick user with all firestore data:

func fetchUser(){
    
    db.collection("users").document(currentUser!.uid)
        .getDocument { (snapshot, error ) in
            do {
                if let document = snapshot {
                    
                    let id = document.documentID
                    let firstName = document.get("firstName") as? String ?? ""
                    let secondName = document.get("secondName") as? String ?? ""
                    let imageUrl = document.get("imageUrl") as? String ?? ""
                    let joinedDate = document.get("joinedDate") as? String ?? ""
                    let coins = document.get("coins") as? Int ?? 0
                    let challenges = document.get("activeChallenges") as? [Challenge] ?? []
                    
                    let imageLink = URL(string: imageUrl)
                    
                    let imageData = try? Data(contentsOf: imageLink!)
                    
                    let image = UIImage(data: imageData!) as UIImage?
                    
                    let arrayWithNoOptionals = document.get("activeChallenges").flatMap { $0 }
                    print("array without opt", arrayWithNoOptionals)
                    
                    self.user = Account(id: id, firstName: firstName, secondName: secondName, email: "", password: "", profileImage: image ?? UIImage(), joinedDate: joinedDate, coins: coins, activeChallenges: challenges)
                }
                else {
                    print("Document does not exist")
                    
                }
            }
            catch {
                fatalError()
            }
        }
}

This is what the user model looks like:

class Account {
var id: String?
var firstName: String?
var secondName: String?
var email: String?
var password: String?
var profileImage: UIImage?
var coins: Int?
var joinedDate: String?
var activeChallenges: [Challenge]?


init(id: String, firstName: String,secondName: String, email: String, password: String, profileImage: UIImage, joinedDate: String, coins: Int, activeChallenges: [Challenge]) {
    self.id = id
    self.firstName = firstName
    self.secondName = secondName
    self.email = email
    self.password = password
    self.profileImage = profileImage
    self.joinedDate = joinedDate
    self.coins = coins
    self.activeChallenges = activeChallenges
}

init() {
    
}

}

The problem is I don't understand how to map the activeChallenges from firestore to the array of the model. When I try : let challenges = document.get("activeChallenges") as? [Challenge] ?? [] The print contains an empty array, but when i do: let arrayWithNoOptionals = document.get("activeChallenges").flatMap { $0 } print("array without opt", arrayWithNoOptionals)

This is the output of the flatmap: it returns an optional array

enter image description here

1
  • 1
    You can’t cast to [Challenge], you need to use .map. Commented May 16, 2021 at 16:14

1 Answer 1

3

System can not know that activeChallenges is array of Challenge object. So, you need to cast it to key-value type (Dictionary) first, then map it to Challenge object

let challengesDict = document.get("activeChallenges") as? [Dictionary<String: Any>] ?? [[:]]
let challenges = challengesDict.map { challengeDict in
    let challenge = Challenge()
    challenge.challengeId = challengeDict["challengeId"] as? String
    ...
    return challenge
}

This is the same way that you cast snapshot(document) to Account object

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.