Nick Gangalo
Nick Gangalo

Reputation: 31

Populating UITableView from Firestore

This feels very basic but I can't get it to work. The content read from FIrestore is not displayed in the tableview. From what I can gather the tableview is rendered before the scheduleArray array is populated from FIrestore. If I make the scheduleArray literal everything works just fine. The print statement in loadData() function prints the content of the db just fine. So the connection to Firestore is working as expected.

How do I get the db read and array population to occur before the rendering of the tableview?

class ListScheduleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var scheduleIDarray = [String]() // <-- If this is made an array literal, everything works
    var db: Firestore!
    override func viewDidLoad() {
        super.viewDidLoad()

        db = Firestore.firestore()
        loadData()

    }
    func loadData() {
        db.collection("schedules").getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {

                    self.scheduleIDarray.append(document.documentID)
                }
            }
            print(self.scheduleIDarray) // <-- This prints the content in db correctly
        }
    }
       @IBOutlet weak var tableView: UITableView!

    //Tableview setup
    func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

                print("Tableview setup \(scheduleIDarray.count)")
        return scheduleIDarray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customScheduleCell", for: indexPath) as! customScheduleviewCell
        let schedule = scheduleIDarray[indexPath.row]

        cell.scheduleName.text = schedule
        print("Array is populated \(scheduleIDarray)")
        return cell
    }

}

Upvotes: 2

Views: 2377

Answers (3)

Nick Gangalo
Nick Gangalo

Reputation: 31

Here is the working code, it might help someone else. There are no checks, no safety, just a very basic but working code.

class ListScheduleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var scheduleIDarray = [String]()
    var db: Firestore!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        db = Firestore.firestore()
        loadData()

    }
    func loadData() {
        db.collection("schedules").getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {

                    self.scheduleIDarray.append(document.documentID)
                }
            }
            print(self.scheduleIDarray) 

            self.tableView.reloadData()
        }

    }
       @IBOutlet weak var tableView: UITableView!

    //Tableview setup
    func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

                print("Tableview setup \(scheduleIDarray.count)")
        return scheduleIDarray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customScheduleCell", for: indexPath) as! customScheduleviewCell
        let schedule = scheduleIDarray[indexPath.row]

        cell.scheduleName.text = schedule
        print("Array is populated \(scheduleIDarray)")

        return cell
    }

}

Upvotes: 1

Chanchal Chauhan
Chanchal Chauhan

Reputation: 1560

Create an outlet of tableView in your viewController as: @IBOutlet weak var tableView: UITableView! and write given lines in viewDidLoad()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    tableView.delegate = self
}

Reload tableView when you successfully received data.

Upvotes: 2

ferbass
ferbass

Reputation: 859

I can see 2 things missing in the code

1 - you need to set the UITableView datasource to be able to load the data into in your tableView

2 - after get the data that you need from Firestone you need to reload your data by using tableView.reloadData() it will call the tableViewDataSource methods responsasses to populate your tableView

Upvotes: 0

Related Questions