iosswiftfirebasegoogle-cloud-firestorecompletionhandler

Global array showing as empty after adding data in a completion handler (Swift)


What I am trying to achieve is load a UITableView with users after I have retrieved all data from Google Firestore and set it to my global array (self.activeUsers). Inside the closure I am able to see the array properly adding the elements but when I try to use this global variable anywhere else (for instance in the viewDidLoad() method) it shows it as an empty array. I am new to Swift so I know there is something silly I am not understanding here with maybe an async call or completion handling. There's a lot of code in here I feel like can be ignored since I know the overall issue is my global variable self.activeUsers contains no data in viewDidLoad however, I can see it correctly being set in fetchActiveUsers()

 override func viewDidLoad() {
        super.viewDidLoad()

        let myCompletionHandler: () -> Void = {
            print("Count in viewDidLoad: ", self.activeUsers.count) // activeUsers count is 0 here. But why?
            self.loadActiveUsersTableView()
        }
        fetchActiveUsers(using: myCompletionHandler)
    }

    func loadActiveUsersTableView() {
        self.view.addSubview(activeUsersTableView)
        self.activeUsersTableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate(
            [
                self.activeUsersTableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 150),
                self.activeUsersTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 30),
                self.activeUsersTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -280),
                self.activeUsersTableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -250),
            ]
        )
        self.activeUsersTableView.reloadData()
    }

    func fetchActiveUsers(using completionHandler: @escaping () -> Void) {
        let myCompletionHandler: (UserProfile?) -> Void = { theUser in
            self.activeUsers.append(theUser!)
            print("Count in fetchActiveUsers myCompletionHandler", self.activeUsers.count) // Able to see this increment correctly after adding a user
        }
        self.chatsDocRef!.getDocument { document, error in
            if let error = error as NSError? {
                print("Error getting document: \(error.localizedDescription)")
            }
            else {
                if let document = document {
                    let data = document.data()
                    self.activeUserUIDS = data?["users"] as? [String]
                    for i in 0..<(self.activeUserUIDS?.count ?? 0) {
                        print("Retrieving document for user ID: ", self.activeUserUIDS![i])
                        let userDocRef = Firestore.firestore().collection("users").document(self.activeUserUIDS![i])
                        UserProfile.getUserProfileData(userDocRef, using: myCompletionHandler)
                    }
                    completionHandler()
                }
            }
        }
    }

Solution

  • Reloading the data inside the completion handler was key to fixing my issue however, I also needed to make a custom design cell class and use prepareForReuse for my UITableView