Andrei Georgescu
Andrei Georgescu

Reputation: 86

Not able to save data from Firebase database to an Array

*I'm fairly new to swift

I'm currently using Swift 4, Xcode 9, and Firebase. My goal is to create an app that stores data in a list, displays it in a table view, and allows the user to add more data to the list. I'm stuck on the displaying data part, I created a function that is supposed to get the data from the database, then add it into an array so that I can display individual parts of it on a custom table view cell. Here's my code:

class OrdersPage: UIViewController, UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return orders.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath) as! OrderCell
    cell.setOrder(order: orders[indexPath.row])
    print("Adding new cell")
    return cell
}

@IBOutlet weak var tableView: UITableView!
var ref: DatabaseReference!
var orders = [Order]()

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self

    self.ref = Database.database().reference()
    orders = getOrders()
}

func getOrders() -> [Order] {
    var tempArray = [Order]()
    ref.child("Orders").observe(.value) { (snapshot) in
        for child in snapshot.children {
            let orderDB = child as! DataSnapshot
            let orderDict = orderDB.value as! [String: Any]

            let name = orderDict["name"] as! String
            let date = orderDict["date"] as! String
            let time = orderDict["time"] as! String
            let hotel = orderDict["hotel"] as! String
            let room = orderDict["room"] as! String
            let airport = orderDict["airport"] as! String
            let agent = orderDict["agent"] as! String
            let price = orderDict["price"] as! String
            //let submitted = orderDict["submitted"] as! String
            tempArray.append(Order(name: name, date: date, time: time, hotel: hotel, room: room, airport: airport, agent: agent, price: price))
        }
    }
    return tempArray
}

Based off of my testing, the issue is that the orders array doesn't contain anything when the numberOfRowsInSection is called so it doesn't create any cells in the table view. I'm not sure why it's not working as it should and have been stuck on this for quite some time now, any help is appreciated.

Upvotes: 1

Views: 344

Answers (2)

Sunil M.
Sunil M.

Reputation: 564

You can use didSet during define your variable of self.orders for reloading UITableView

Here your table will automatically reload when any data is assigned to self.orders

Replace your declaration

var orders = [Order]()

with below code

var orders : [Order] = [] {
        didSet {
            tableView.reloadData()
        }
    }

Upvotes: 0

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71854

getOrders() is Asynchronous call so you need to reload your table after you got data from server.

Here is the way you can achieve that.

Replace:

func getOrders() -> [Order]

with

func getOrders()

And your getOrders method will look like:

func getOrders() {

    ref.child("Orders").observe(.value) { (snapshot) in
        for child in snapshot.children {
            let orderDB = child as! DataSnapshot
            let orderDict = orderDB.value as! [String: Any]

            let name = orderDict["name"] as! String
            let date = orderDict["date"] as! String
            let time = orderDict["time"] as! String
            let hotel = orderDict["hotel"] as! String
            let room = orderDict["room"] as! String
            let airport = orderDict["airport"] as! String
            let agent = orderDict["agent"] as! String
            let price = orderDict["price"] as! String
            //let submitted = orderDict["submitted"] as! String

            //Add your data into array
            self.orders.append(Order(name: name, date: date, time: time, hotel: hotel, room: room, airport: airport, agent: agent, price: price))
        }

        //Reload your tableView here
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}

I have updated inner code. Check comments.

Now in your viewDidLoad method Replace:

orders = getOrders()

With

getOrders()

Upvotes: 1

Related Questions