Home > other >  Array populated from Firebase returned empty, but data was retrieved. Why?
Array populated from Firebase returned empty, but data was retrieved. Why?

Time:07-24

Still learning some swift and managed to advance and retrieving data from a firestore database. I have a Data Controller whose task is to offload all the data retrieving from firestore. It does the calls and gets data, but when returning the info from the first function I have implemented on it, it's empty.

Here's an example of the funcion:

func fetchUnidades(for foo: MyFirstEnum, and bar: MySecondEnum ) -> [MyClassType]{
    
    let db = Firestore.firestore()
    let colPath = "my/firebase/path"
    let results = [MyClassType]()
    let collection = db.collection(colPath)
    
    collection.whereField("myField", isEqualTo: foo.rawValue).getDocuments() { querySnapshot, err in
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            for document in querySnapshot!.documents {
                do {
                    print("\(document.documentID) => \(document.data())") // 1st print
                    let newMyClass = try document.data(as: MyClassType.self)
                    results.append(newMyClass)
                    print("here") // 2nd print - debug breakpoint
                }catch (let error) {
                    print("\(error)")
                }
            }
        }
    }
    print("DC - Recovered \(results.count) results")
    return results
}

Assume MyFirstEnum, MySecondEnum and MyClassType are correct, because the database retrieves info. On the 1st print line, there's output for data retrieved, and on the 2nd print - debug breakpoint line, if I do a po results, it has one value, which is the one retrieved as you can see here:

PO output of the item loaded from the Firestore database

unidades being the name on my code of results on this example.

But right after continuing with the execution, unidades, aka results is empty, the line: print("DC - Recovered \(results.count) results") prints DC - Recovered 0 results and the return also returns an empty array with zero values on it.

Any idea about why this might be happening? And how to solve the issue? Obviously the goal is to return the info...

CodePudding user response:

That's because the result comes asynchronously. Your fetchUnidades returns results array before it's populated.

You need to add a completion closure in this case. Instead of returning results you call that completion closure and pass the results as its argument.

func fetchUnidades(for foo: MyFirstEnum, and bar: MySecondEnum, completion: (results: [MyClassType]?, error: Error?) -> Void) {
let db = Firestore.firestore()
let colPath = "my/firebase/path"
let collection = db.collection(colPath)

collection.whereField("myField", isEqualTo: foo.rawValue).getDocuments() { querySnapshot, err in
    if let err = err {
        print("Error getting documents: \(err)")
        completion(nil, err)
    } else {
       let results = [MyClassType]()
       for document in querySnapshot!.documents {
            do {
                print("\(document.documentID) => \(document.data())") // 1st print
                let newMyClass = try document.data(as: MyClassType.self)
                results.append(newMyClass)
                print("here") // 2nd print - debug breakpoint
            }catch (let error) {
                print("\(error)")
            }
        }
        completion(results, nil)
    }
}
  • Related