Kiran Lim
Kiran Lim

Reputation: 39

Can't display data from firebase documents on a tableview

I have an array that stores data for a table view, and I need my app to retrieve data from firebase, and then append it into the data array to be displayed onto my table view. but for some reason all the cells in the table view are packed together closely after I added the line assignmentstableview.reloadData(). And when I remove assignmentstableview.reloadData(), the data doesn't show up at all. Anyone knows how to retrieve data from firebase documents, and then display it on my tableview? code is shown below:

import Firebase
import FirebaseAuth


class AssignmentsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    struct assignmentmodal {
        let name: String
        let duedate: String
        let imagename: String
    }
    
    var data: [assignmentmodal] = []
    
    
    @IBOutlet weak var titleLabel: UILabel!
    
    @IBOutlet weak var titleView: UIView!
    
    
    @IBOutlet weak var plusbtn: UIButton!
    
    @IBOutlet weak var codeLabel: UILabel!
    
    @IBOutlet weak var assignmentstableview: UITableView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        syncAssignments()
        data.append(assignmentmodal(name: "test2", duedate: "test2", imagename: ""))
        titleLabel.text = "\(ClassesViewController.shared.chosenClass)"
        print(ClassesViewController.shared.chosenClass)
        let gradientFirstColor = UIColor(hex: "9d81e0").cgColor
        let gradientSecondColor = UIColor(hex: "6d5cd3").cgColor
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = titleView.bounds
        gradientLayer.colors = [gradientFirstColor, gradientSecondColor]
        gradientLayer.cornerRadius = 21
        gradientLayer.masksToBounds = true
        titleView.layer.insertSublayer(gradientLayer, at: 0)
        displayInfo(classname: ClassesViewController.shared.chosenClass)
        setTableView()
        titleView.layer.cornerRadius = 21
        
        
        // Do any additional setup after loading the view.
    }
    
    @IBAction func unwindsegue(_ sender: Any) {
        print("button works")
        performSegue(withIdentifier: "unwind", sender: self)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        syncAssignments()
    }
    let db = Firestore.firestore()
    let user = Auth.auth().currentUser
    func syncAssignments() {
        db.collection("Classes").document(ClassesViewController.shared.chosenClass).collection("Assignments").getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    if let name = document.get("name"), let duedate = document.get("due date") {
                        print("\(name)")
                        print("\(duedate)")
                        self.data.append(assignmentmodal(name: "\(name)", duedate: "\(duedate)", imagename: ""))
                        self.assignmentstableview.reloadData()
                        self.setTableView()
                    }
                }
            }
        }
    }
    
    func setTableView() {
        assignmentstableview.backgroundColor = UIColor.clear
        assignmentstableview.delegate = self
        assignmentstableview.dataSource = self
        
        assignmentstableview.register(AssignmentCellTableViewCell.self, forCellReuseIdentifier: "Cell")
    }
    
    
    
    
    @IBAction func plusAssignment(_ sender: Any) {
        
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let assignments = data[indexPath.row]
        let cell = assignmentstableview.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! AssignmentCellTableViewCell
        cell.image.image = UIImage(named: assignments.imagename)
        cell.assignmentname.text = assignments.name
        cell.duedate.text = assignments.duedate
        print("\(assignments.name)")
        print("\(assignments.duedate)")
        return cell
    }
    
    func displayInfo(classname: String) {
        let db = Firestore.firestore()
        db.collection("Classes").whereField("name", isEqualTo: classname)
            .getDocuments() { (querySnapshot, err) in
                if let err = err {
                    print("Error getting documents")
                } else {
                    for document in querySnapshot!.documents {
                        if let teacher = document.get("teacher"), let code = document.get("code") {
                            print(code)
                            self.codeLabel.text = "\(code)"
                            
                            let user = Auth.auth().currentUser
                            if let email = user?.email {
                                print("\(email)")
                                let docRef = db.collection("Users").document("[email protected]")
                                docRef.getDocument { (document, error) in
                                    if let document = document, document.exists, let username = document.get("username") {
                                        if username as! String == teacher as! String {
                                            self.plusbtn.isHidden = false
                                        }
                                        else {
                                            self.plusbtn.isHidden = true
                                        }
                                    } else {
                                        print("Document does not existdisplay")
                                    }
                                }
                            }
                        }
                    }
                }
        }
        
    }
    
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */
    
    
    
}

my cell class:


import UIKit

class AssignmentCellTableViewCell: UITableViewCell {
    
    lazy var backview: UIView = {
        let view = UIView(frame: CGRect(x: 10, y: 6, width: 340, height: 110))
        view.backgroundColor = UIColor.white
        return view
    }()
    
    lazy var image: UIImageView = {
        let image = UIImageView(frame: CGRect(x: 4, y: 15, width: 80, height: 80))
        image.contentMode = .scaleAspectFill
        return image
    }()
    
    lazy var assignmentname: UILabel = {
        let assignmentname = UILabel(frame: CGRect(x: 116, y: 8, width: backview.frame.width - 88, height: 25))
        assignmentname.textAlignment = .left
        assignmentname.font = UIFont.boldSystemFont(ofSize: 20)
        return assignmentname
    }()
    
    lazy var duedate: UILabel = {
        let duedate = UILabel(frame: CGRect(x: 116, y: 42, width: backview.frame.width - 88, height: 25))
        duedate.textAlignment = .left
        duedate.font = UIFont.systemFont(ofSize: 10)
        return duedate
    }()

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }
    
    override func layoutSubviews() {
        backview.layer.cornerRadius = 15
        backview.clipsToBounds = true
        backview.layer.borderColor = UIColor.systemGray5.cgColor
        backview.layer.borderWidth = 1
        image.layer.cornerRadius = 40
        image.clipsToBounds = true
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        addSubview(backview)
        backview.addSubview(image)
        backview.addSubview(assignmentname)
        backview.addSubview(duedate)
        // Configure the view for the selected state
    }

}

and this is how it looks like when the cells are packed together:

enter image description here

Upvotes: 0

Views: 46

Answers (1)

DianaRojas
DianaRojas

Reputation: 71

I suggest you switch your calls of self.assignmentstableview.reloadData() and self.setTableView() you need the delegate call before reload the data of the table.

Actually, your function func setTableView() only needs to be called once, and it should be called before self.assignmentstableview.reloadData()

If that doesn't work maybe the problem is related to your Firestore.

Upvotes: 1

Related Questions