2

Based on what I have read on the documentation page on Firestore, after I get the document, completion handler (aka the closure) should be called. I have the following code and I am trying to display a field from every document from a collection from Firestore but when I run the app, it doesn't work. The label from every cell isn't changed.

Later Edit: Also, scrolling through the tableview is really buggy and when you scroll down and try to scroll up again you it won't go up, it will just shake.

import UIKit
import Firebase
import FirebaseFirestore

class AnunturiViewController: UITableViewController {

    var anunturi: [Produs] = [Produs]()
    var docRef: DocumentReference!
    var docRefNrTotalProduse: DocumentReference!
    var nrTotalProduse = 0
    var isDone = false

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchData()
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ADCell") as! ADTableViewCell
        if isDone == true {
            cell.denumireAnuntLabel.text = anunturi[nrTotalProduse - indexPath.row].denumire
        }
        return cell
    }

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

        docRefNrTotalProduse = Firestore.firestore().collection("nrproduse").document("nrproduse")

        docRefNrTotalProduse.getDocument { (snapshot, error) in
            if error != nil { print(error ?? "0") }
            else {
                let data = snapshot?.data()
                self.nrTotalProduse = data!["nrtotalproduse"] as! Int
                tableView.reloadData()
            }
        }

        return nrTotalProduse
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 164.0
    }

    @IBAction func onRefreshButtonPressed(_ sender: UIBarButtonItem) {
        tableView.reloadData()
    }

    func fetchData() {
        var i = 0
        while(i < nrTotalProduse) {
            docRef = Firestore.firestore().collection("produse").document(String(nrTotalProduse - i))

            docRef.getDocument { (snapshot, error) in
                let data = snapshot?.data()
                let produs = Produs(denumire: (data?["nume"] as? String)!)
                self.anunturi.append(produs)
                DispatchQueue.main.async {
                    if i == self.nrTotalProduse - 1 {
                        self.isDone = true
                        self.tableView.reloadData()
                    }
                }
            }

            i += 1
        }
    }

}
F. Dolha
  • 103
  • 1
  • 2
  • 13
  • one question, the closure is not being called (not executing any line inside the closure) or the tableView is not showing anything? – thxou Jun 14 '18 at 09:31
  • The tableview is showing the cells as the prototype that are I have created, but the not with the data from Firebase – F. Dolha Jun 14 '18 at 09:38
  • Also, I get a bunch of messages called 'TIC' in the console, what does those mean? – F. Dolha Jun 14 '18 at 10:59
  • here is the answer for your later question: https://stackoverflow.com/questions/46352735/what-is-tic-read-status-157-in-ios11-xcode-9 – thxou Jun 14 '18 at 11:09
  • I also get these errors: Task <803C8E0B-B42E-42F1-8AC5-E4A25B14ADDA>.<2> finished with error - code: -1003 2018-06-14 13:58:10.039638+0300 Hyype[8178:2311609] Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service 2018-06-14 13:58:10.040701+0300 Hyype[8178:2311609] Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service – F. Dolha Jun 14 '18 at 11:13

1 Answers1

2

First: I think the main issue is because self.isDone = true is never executed. The reason I think this is because at the time you call fetchData, nrTotalProduse will always be 0, so the execution flow will never enter to the while loop.

Second: You see the cells as they look in the prototypes because numberOfRowsInSection is being called and returning a number that you set to nrTotalProduse, but because the isDone variable is never set to true, cells are not being set with the corresponding value.

Third: The "buggy" scroll you experience is because what you are calling inside the numberOfRowsInSection method. This method will be called whenever you call tableView.reloadData, so what you are doing is keeping a loop of calls that will never end inside this method, resulting in a call to reloadData such many times that you can even see the scroll.

Totally avoid this kind of calls inside the numberOfRowsInSection method.

Edit:

If what you are trying to do is get all the documents in the produse collection, I strongly recommend changing the fetchData method to something like this:

func fetchData() {
    docRef = Firestore.firestore().collection("produse")
    docRef.getDocuments() { (querySnapshot, error) in
        if let error = error {
            print("Error getting documents: \(error)")
        } else {
            for document in querySnapshot!.documents {
                let data = document.data()
                let produs = Produs(denumire: (data?["nume"] as? String)!)
                self.anunturi.append(produs)
            }

            self.isDone = true
            self.tableView.reloadData()
        }
    }
}
thxou
  • 691
  • 7
  • 20
  • Ok, so, I've changed a few things and so I moved the fetching data to collect nrTotalProduse in viewDidLoad and I set the nrTotalProduse to be a computed property, so when didSet is called, the fetchData function is called. The "buggy" scroll has gone, but still it isn't chaning the label, I've checked with a print statement and now when it enters in fetchData, nrTotalProduse is correct to what I want. – F. Dolha Jun 14 '18 at 10:51
  • put a breakpoint at the line `self.isDone = true` to see if `isDone` is being set – thxou Jun 14 '18 at 10:53
  • I put also a print and both of them weren't called, so here is the problem, should this be changed to a for loop or the loop is not the problem? – F. Dolha Jun 14 '18 at 10:56