Jordan Lewallen
Jordan Lewallen

Reputation: 1861

Issue with first Firebase query item out of order until refresh

I have a firebase database to pull 50 users with the highest integer value and to display them from highest to lowest. The issue will arise when I enter the leaderboard view for the first time. The order should show jlewallen18 at the top AND THEN appledev. But on first load appledev is at the top, until I back out and open the leaderboard again (code at the bottom).

enter image description here

Leaderboard code:

class LeaderboardViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var leaderboardTableView: UITableView!

    var userModel : [User] = [User]()

    let pipeline = ImagePipeline {
    //config settings for image display removed for brevity
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        leaderboardTableView.delegate = self
        leaderboardTableView.dataSource = self

        fetchUsers()
    }

    func fetchUsers() {
        let queryRef = Database.database().reference().child("users").queryOrdered(byChild: "ranking").queryLimited(toLast: 50)
        queryRef.observe(.childAdded, with: { (snapshot) in
            if let dictionary = snapshot.value as? [String : AnyObject]{
                let user = User(dictionary: dictionary)
                self.userModel.append(user)
            }
            DispatchQueue.main.async(execute: {
                self.leaderboardTableView.reloadData()
            })
        })
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "leaderboardTableCell", for: indexPath) as! LeaderboardTableCell
        if userModel.count > indexPath.row {
            if let profileImageURL = userModel[indexPath.row].photoURL {
                let url = URL(string: profileImageURL)!
                var options = ImageLoadingOptions()
                options.pipeline = pipeline
                options.transition = .fadeIn(duration: 0.25)
                Nuke.loadImage(
                    with: ImageRequest(url: url).processed(with: _ProgressiveBlurImageProcessor()),
                    options: options,
                    into: cell.userImage
                )
            }
        }
        cell.userName.text = userModel[indexPath.row].username
        cell.watchTime.text = "\(String(describing: userModel[indexPath.row].watchTime!))"
        cell.ranking.text = "\(indexPath.row + 1)"
        cell.userImage.layer.cornerRadius = cell.userImage.frame.size.width/2
        return cell
    }
}

I thought it might be because I am using the same model name userModel in both my Profile page view and my Leaderboard view but when i changed the model name in my leaderboard view nothing changed. What else can I share to help? Thanks!

EDIT: here's my console output after printing out watchTime which is the integer I have rankings for:

HERES WHERE I OPEN LEADERBOARD PAGE FIRST:
Optional(28)
Optional(247)
Optional(0)
Optional(0)
Optional(0)
Optional(0)
AFTER I GO BACK AND CLICK TO VIEW LEADERBOARD AGAIN:
Optional(247)
Optional(28)
Optional(0)
Optional(0)
Optional(0)
Optional(0)

Upvotes: 2

Views: 75

Answers (1)

Casey West
Casey West

Reputation: 576

The issue here is related to this line of code...

let queryRef = Database.database().reference().child("users").queryOrdered(byChild: "ranking").queryLimited(toLast: 50)

Changing this limit to 10 makes the app work as expected, which is a temporary 'fix'.

If we figure out why that limit is causing issues I'll be sure to update this answer.

Upvotes: 2

Related Questions