iosswiftfirebasegoogle-cloud-firestore

Firestore into TableView [Swift]


I've already seen: Swift UITableView reloadData in a closure but it still does not work. That's why I'm creating a new thread for this.

I'm trying to insert Firestore data into a custom tableview. But when I print the numbers it returns (In the console):

"MyDogwalk.listTxt"

And no data is showing up on the tableview.

I guess all of this is relevant. (I also have 2 classes, with init etc)

class HistoryViewController: UIViewController {

    //Tableview
    @IBOutlet weak var tableView: UITableView!
    
    let db = Firestore.firestore()
    
    var list: [listTxt] = []
    
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        list = createArray()
        
        tableView.delegate = self
        tableView.dataSource = self
    }
    
    func createArray() -> [listTxt]
    {
        var tempTxt: [listTxt] = []
        
        //Authentication
        let authentication = Auth.auth().currentUser?.uid
        
        //Choosing collection
        db.collection("rastad").document(authentication!).collection("promenad").getDocuments()
            { (QuerySnapshot, err) in
                if err != nil
                {
                    print("Error getting documents: \(String(describing: err))");
                }
                else
                {
                    //For-loop
                    for _ in QuerySnapshot!.documents
                    {
                        self.list.removeAll()
                        let document = QuerySnapshot!.documents.first
                        let data = document!.data()
                        data.forEach { (item) in
                            
                            let data1 = data["Dog"] as? String
                            let data2 = data["Person"] as? String
                            let data3 = data["What"] as? String
                            let data4 = data["Date"] as? String
                            let data5 = data["Time"] as? String
                            
                            
                            let txt = listTxt(dog: data1!, person: data2!, action: data3!, time: data4!, date: data5!)
                            print(txt)
                            
                            tempTxt.append(txt)
                        }
                        
                    }
                    self.tableView.reloadData()
                }
        }
        
        //return tempTxt
        return list
    }
}

extension HistoryViewController: UITableViewDelegate, UITableViewDataSource
{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return list.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let listPath = list[indexPath.row]
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! HistoryCell
        
        cell.setCell(list: listPath)
        
        return cell
    }
    
    
}

Solution

  • createArray() method runs async code, and fills tempTxt. But you are returning tempTxt before async code has been run. So instead returning from createArray method and setting its value to self.list, just do it in the method itself:

    self.list = tempTxt
    self.tableView.reloadData()
    

    You are iterating over documents but always using data of documents.first. Try this:

    self.list.removeAll()
    
    for document in QuerySnapshot!.documents {
      let data = document!.data()
      data.forEach { (item) in
    
      let data1 = data["Dog"] as? String
      let data2 = data["Person"] as? String
      let data3 = data["What"] as? String
      let data4 = data["Date"] as? String
      let data5 = data["Time"] as? String
    
      self.list.append(listTxt(dog: data1!, person: data2!, action: data3!, time: data4!, date: data5!))
      }
    }
    
    self.tableView.reloadData()