'How I can get all of users lists from Firestore?

class UsersViewModel : ObservableObject {
    
    @Published var users = [CurrentUser]()
    
    init() {
        fetchUserLists()
        print(users)
    }
    
    func fetchUserLists() {
        
        FirebaseManager.shared.firestore.collection("users")
            .getDocuments { documentSnapshot, error in
                if let error = error {
                    print("Error to get user lists")
                    return
                }
                //success
                documentSnapshot?.documents.forEach({ snapshot in
                    let user = try? snapshot.data(as: CurrentUser.self)
                    if user?.uid != FirebaseManager.shared.auth.currentUser?.uid {
                        self.users.append(user!)
                    }
                })
            }
    }
    
}

I'm trying to fetch all of users in my firestore database, but unfortunately my users array is empty. I don't know what my mistake is.

Please check my firestore screen shot, and give me tips! Thank you!

enter image description here



Solution 1:[1]

You're having an issue with asynchronous code. Code is faster than the internet and you have to allow time for data to be retrieved from Firebase.

Additionally, Firebase data is only valid within the closure following the Firebase call. In this case your code is attempting to print an array before it's been filled.

Here's the issue

init() {
   fetchUserLists() //<-takes time to complete
   print(users) //this is called before fetchUserLists fills the array
}

here's the fetchUserLists function with where the print statement should be

func fetchUserLists() {
    FirebaseManager.shared.firestore.collection("users").getDocuments { documentSnapshot, error in
        if let error = error {
            print("Error to get user lists")
            return
        }
        documentSnapshot?.documents.forEach({ snapshot in
            let user = try? snapshot.data(as: CurrentUser.self)
            if user?.uid != FirebaseManager.shared.auth.currentUser?.uid {
                self.users.append(user!)
            }
        })
        print(self.users) //we are within the closure and the array is now populated
        //this is a good spot to, for example, reload a tableview
        //  or update other UI elements that depend on the array data
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jay