14wml
14wml

Reputation: 4166

Data from Firebase not loading into array

I don't have a storyboard. I'm doing everything programmatically.

The loadData() method takes Firebase data, put it into a Company object, and loads the object into the companies array. In the didFinishLaunchingWithOptions method in the App Delegate, I instantiated the class and called loadData()

When I run breakpoint at the line indicated by the comment and type "po companies" in the console, I get 0 companies. The print statements inside .observe are printed to the console and I can see that the company's properties are non-null, but anything outside .observe, including the for loop and the print statement called after the load data method in the App Delegate are not printed.

class informationStateController {    
func loadData() {
    //Set firebase database reference
    ref = FIRDatabase.database().reference()

    //Retrieve posts and listen for changes
    databaseHandle = ref?.child("companies").observe(.childAdded, with: { (snapshot) in
        //Code that executes when child is added
        let company = Company()
        company.name = snapshot.childSnapshot(forPath: "name").value as! String
        print(company.name)
        company.location = snapshot.childSnapshot(forPath: "location").value as! String
        print(company.location)
        self.companies.append(company)
        print("databaseHandle was called")
    })

    for company in companies {
        print(company)
    }
    //breakpoint inserted here

}
}

Why is my array empty and why are print statements outside .observe NOT printing to the console? The output for the console is set to "All Output". I called import FirebaseDatabase in the class and import Firebase in the App Delegate.

Upvotes: 1

Views: 1226

Answers (2)

brandonscript
brandonscript

Reputation: 72825

Per the docs (emphasis mine)

Important: The FIRDataEventTypeValue event is fired every time data is changed at the specified database reference, including changes to children. To limit the size of your snapshots, attach only at the highest level needed for watching changes. For example, attaching a listener to the root of your database is not recommended.

In your case, you're observing changes to the database, but no changes are happening, so you won't bet getting new data. I think the docs make this unnecessarily confusing, if you want to pull records that already exist, you have to query for it:

https://firebase.google.com/docs/database/ios/lists-of-data#sort_data

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("companies").queryLimited(toFirst: 100))!

Once you have that queried data, you can then deal with the observer and append data as required when new data is pushed.

All of this aside, Frank's answer is the reason you'll never see the print when a company is added even if you set the listener up right — you need to write that inside the completion block of the observer or query.

Upvotes: 0

Frank van Puffelen
Frank van Puffelen

Reputation: 598603

Data is loaded from the Firebase Database asynchronously. This means that by the time you print the companies, they won't have loaded yet.

You can easily see this by also printing the companies as they're loaded:

//Set firebase database reference
ref = FIRDatabase.database().reference()

//Retrieve posts and listen for changes
databaseHandle = ref?.child("companies").observe(.childAdded, with: { (snapshot) in
    //Code that executes when child is added
    let company = Company()
    company.name = snapshot.childSnapshot(forPath: "name").value as! String
    print(company.name)
    company.location = snapshot.childSnapshot(forPath: "location").value as! String
    print(company.location)
    self.companies.append(company)
    print("databaseHandle was called")
    for company in companies {
        print(company)
    }
})

Now you'll first see one company printed (when childAdded fires for the first time), then two companies (when childAdded fires again), then three companies, etc.

Upvotes: 2

Related Questions