skip to Main Content

I am currently building an app using firebase as the database. I am trying to fetch the categories of my user, however, even though I can see in my firebase console that the user actually has 3 categories (I added them by default upon registration).

I tried to debug but could not figure out why it happens. Furthermore, I looked for similar problems and moved my code when I call the function into the .onAppear method. None of these attempts worked…

Here is my firebase console:
Firebase Console

Code for fetching categories:

func fetchCategories(forUserId userId: String, completion: @escaping (Result<[Category], Error>) -> Void) {
        
        let categoriesRef = db.collection("users").document(userId).collection("categories")
        print("user id: (userId)")
        categoriesRef.getDocuments { (snapshot, error) in
            if let error = error {
                completion(.failure(error))
                return
            }

            guard let documents = snapshot?.documents else {
                completion(.failure(FirestoreErrorCode.notFound as! Error))
     
                return
            }

            let categories = documents.compactMap { document -> Category? in
                do {
                    return try document.data(as: Category.self)
                } catch {
                    print("Error decoding category: (error)")
                    return nil
                }
            }

            completion(.success(categories))
        }
    }

Calling the function:

.onAppear {
                FirebaseManager().fetchCategories(forUserId: Auth.auth().currentUser?.uid ?? "") { result in
                    do {
                        let categories = try result.get()
                        print("fetched categories")
                        print(categories.isEmpty ? categories : categories[0])
                        if categories.isEmpty == false {
                            firstCategory = categories[0]
                        }
                    } catch {
                        print("Error fetching categories: (error.localizedDescription)")
                    }
                    
                }
            }

If I should provide anything else, please just say!

2

Answers


  1. You need to hold a strong reference to your object

    @StateObject var fm = FirebaseManager()
    

    Then

    fm.fetchCategories.....
    

    A side note :- It’s better to put the fetchCategories logic inside the class FirebaseManager and use @Published to reflect the response data to the view , also to use async await with Firebase’s getDocuments instead of the old completion style

    Login or Signup to reply.
  2.         func fetchCategories(forUserId userId: String, completion: @escaping (Result<[Category], Error>) -> Void) {
        let userRef = db.collection("users").document(userId)
        print("user id: (userId)")
        
        userRef.getDocument { (snapshot, error) in
            if let error = error {
                completion(.failure(error))
                return
            }
            guard let document = snapshot, document.exists else {
                completion(.failure(FirestoreErrorCode.notFound as! Error))
                return
            }
            
            do {
                let data = document.data()
                if let categoriesArray = data?["categories"] as? [[String: Any]
                {
                    let categories = try categoriesArray.compactMap { 
                       dict -> Category? in  
                        return try Category(from: dict)
                     }
                    completion(.success(categories))
                } else {
                    completion(.success([])) // Return an empty array if no categories are found
                }
            } catch {
                print("Error decoding category: (error)")
                completion(.failure(error))
            }
        }
    }
    
    
        .onAppear {
        FirebaseManager().fetchCategories(forUserId: Auth.auth().currentUser?.uid ?? "") { result in
            do {
                let categories = try result.get()
                print("fetched categories")
                print(categories.isEmpty ? categories : categories[0])
                if categories.isEmpty == false {
                    firstCategory = categories[0]
                }
            } catch {
                print("Error fetching categories: (error.localizedDescription)")
            }
        }
    }
    

    **Try it and let me know if you are encountering any error post the error here also
    **

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search