Search code examples
arraysfirebasegoogle-cloud-firestoreswiftuifatal-error

SwiftUi : Index out of range on an Array issued from Firestore


I'm new here and learning how to code with SwiftUi

I'm trying to figure out why I can't access to my array values issued from Firestore. The class below read the datas from Firestore and fill an array datas: [category], where category is a struct.

The array seems to be well filled because when i'm printing values of this array it appears in the console.

class getCategoriesData: ObservableObject {

@Published var datas = [category]()

init() {
    let db = Firestore.firestore()

    db.collection("categories").addSnapshotListener { (snap, err) in

        if err != nil {

            print((err?.localizedDescription)!)
            return
        }

        for i in snap!.documentChanges {
            let id = i.document.documentID
            let name = i.document.get("name") as! String
            let pic = i.document.get("pic") as! String

            self.datas.append(category(id: id, name: name, pic: pic))
        }

        //try inside getCategoriesData
        print(self.datas)
        print(self.datas[1])
        print(self.datas[1].name)

    }
}

But when I call my array from my View (code below), i get this error :

"Thread 1: Fatal error: Index out of range"

It seems the array isn't recognized in the View.

struct ContentView: View {

@State private var searchText: String = ""
@ObservedObject var categories = getCategoriesData()

var body: some View {

    VStack {

        Text(categories.datas[1].name) //here the error appears

I don't get the point why I can access to my array from the getCategoriesData while I can't inside my ContentView..

Thanks for your answers Jean


Solution

  • the reason you cannot access your array from the getCategoriesData is because "db.collection("categories").addSnapshotListener { (snap, err) in" is an asynchronous function. That is, the results of it (and therefore init()) are not available until it is finished. Study a bit more about asynchronous functions and where to call them, typically not in init().