I am trying to map firestore documents using Codable in swift. I have tried writing functions that seem to throw up errors. I have now written one that has no errors however the function is within a class. I think this is causing problems
Here is the code for the class & function:
import SwiftUI
import Firebase
import FirebaseFirestoreSwift
class FetchUserVM: ObservableObject {
@Published var user = [UserModel]()
private var db = Firestore.firestore()
func fetchUser() {
db.collection("Users").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No Documents")
return
}
self.user = documents.compactMap { (queryDocumentSnapshot) -> UserModel? in
return try? queryDocumentSnapshot.data(as: UserModel.self)
}
}
}
}
Here is where I am using the fetchUser function. (ProfileViewModel which is a class)
import SwiftUI
import Firebase
class ProfileViewModel : ObservableObject {
@EnvironmentObject var sharedData: SharedDataModel
@Published var userInfo = UserModel(username: "", pic: "", bio: "", uid: "")
@AppStorage("current_status") var log_Status = false
@Published var picker = false
@Published var img_data = Data(count: 0)
@Published var isLoading = false
let ref = Firestore.firestore()
let uid = Auth.auth().currentUser!.uid
init() {
fetchUser(uid: uid) { (user) in
self.userInfo = user
}
}
func logOut(){
// logging out..
try! Auth.auth().signOut()
log_Status = false
}
func updateImage(){
isLoading = true
UploadImage(imageData: img_data, path: "profile_Photos") { (url) in
self.ref.collection("Users").document(self.uid).updateData([
"imageurl": url,
]) { (err) in
if err != nil{return}
// Updating View..
self.isLoading = false
fetchUser(uid: self.uid) { (user) in
self.userInfo = user
}
}
}
}
func updateDetails(field : String){
alertView(msg: "Update \(field)") { (txt) in
if txt != ""{
self.updateBio(id: field == "Name" ? "username" : "bio", value: txt)
}
}
}
func updateBio(id: String,value: String){
ref.collection("Users").document(uid).updateData([
id: value,
]) { (err) in
if err != nil{return}
// refreshing View...
fetchUser(uid: self.uid) { (user) in
self.userInfo = user
}
}
}
}
When i call the fetchUser function, i get the error:
'Cannot find fetchUser in scope'
What is the way around this?
EDITED: I have since changed my fetchUser function. The fetchUser function i had before worked however it was mapping manually which is less than ideal!
Here is the original fetchUser function for this project:
let ref = Firestore.firestore()
func fetchUser(uid: String,completion: @escaping (UserModel) -> ()){
//MARK: Have not tested the following lines...
let db = Firestore.firestore()
@EnvironmentObject var sharedData: SharedDataModel
ref.collection("Users").document(uid).getDocument { (doc, err) in
guard let user = doc else{return}
let username = user.data()?["username"] as? String ?? "No Username"
let pic = user.data()?["imageurl"] as? String ?? "No image URL"
let bio = user.data()?["bio"] as? String ?? "No bio"
let uid = user.data()?["uid"] as? String ?? ""
let isVerified = user.data()?["isVerified"] as? Bool ?? false
DispatchQueue.main.async {
completion(UserModel(username: username, pic: pic, bio: bio, uid: uid, isVerified: isVerified))
}
}
}
This is what i have changed it to (am getting 'Cannot find self in scope errors):
func fetchUser(documentId: String) {
let db = Firestore.firestore()
let docRef = db.collection("Users").document(documentId)
docRef.getDocument { document, error in
if let error = error as NSError? {
self.errorMessage = "Error getting document: \(error.localizedDescription)"
}
else {
if let document = document {
do {
self.user = try document.data(as: UserModel.self)
}
catch {
print(error)
}
}
}
}
}
There is something i am not doing here but everywhere i look i can't find the solution.