首页 > 解决方案 > Firebase query is not populating array for table view. How can I resolve this issue?

问题描述

I have written a firebase query that gets information from my Competition db and then loads it into my distanceData (which is of type distanceModel, a class that I created) before populating the table view. However, the table view is not being populated.

Photo of Firebase db

enter image description here

Photo of distanceModel class

enter image description here

I tried putting print statements in the query to see if the data is being retrieved correctly, but nothing is being printed so the problem is most likely with the query.

var distanceData = [distanceModel]()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate=self
    tableView.dataSource=self
    self.tableView.rowHeight = 200

    refUser = Database.database().reference().child("userInfo");

    let userID = Auth.auth().currentUser!.uid
    let query = refUser?.queryOrdered(byChild: "userId").queryEqual(toValue: "\(userID)")
    query?.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children {
            let childSnap = child as! DataSnapshot
            var dict = childSnap.value as! [String: Any]
            let level=dict["level"] as! String
            if (level=="Beginner") {
                self.refCompetition = Database.database().reference().child("competition1");
            }

            else if (level=="Intermediate") {
                self.refCompetition = Database.database().reference().child("competition2");
            }

            else {
                self.refCompetition = Database.database().reference().child("competition3");
            }
        }
    })

retrieve the posts and listen for changes

refCompetition?.observe(DataEventType.value, with: { (snapshot) in

        for users in snapshot.children.allObjects as! [DataSnapshot] {
            let userObject = users.value as? [String: AnyObject]
            let userName = userObject?["name"] as! String?
            let userDistance = userObject?["distance"] as! String?
            print(userName)
            print(userDistance)


            let dist = distanceModel(name: userName,distance: userDistance)

            self.distanceData.append(dist)
        }
    })

    self.tableView.reloadData()
}

Number of Rows

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

Contents for each cell

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "DistanceCell", for: indexPath) as! DistanceCell

    let dist: distanceModel
    dist = distanceData[indexPath.row]
    cell.nameLabel.text = dist.name
    cell.distanceLabel.text = dist.distance

    cell.rankNumber.text = String (indexPath.row+1)

    return cell
}

It should get the data from the appropriate competition db and then render the results onto the table view.

标签: iosswiftfirebaseuitableviewfirebase-realtime-database

解决方案


Try moving your self.tableView.reloadData() call into the Observer like below

refCompetition?.observe(DataEventType.value, with: { (snapshot) in

        for users in snapshot.children.allObjects as! [DataSnapshot] {
            let userObject = users.value as? [String: AnyObject]
            let userName = userObject?["name"] as! String?
            let userDistance = userObject?["distance"] as! String?
            print(userName)
            print(userDistance)


            let dist = distanceModel(name: userName,distance: userDistance)

            self.distanceData.append(dist)
        }

self.tableView.reloadData()
    })
}

推荐阅读