Neil Leon
Neil Leon

Reputation: 55

My data from firebase database is not loading into my tableview

I have a tableview loading data from firebase database. When I open my app the data does not populate. when I create a new post I can see the tableview cells modifying like changed were made but the post doesn't populate. I can't figure it out.

import UIKit
import FirebaseAuth
import FirebaseDatabase

class EventsViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var eventsRef: DatabaseReference?
    var eventsDatabaseHandle:DatabaseHandle?

    var eventsTitles = [String]()
    var eventTimestamps = [String]()
    var eventsLocations = [String]()
    var eventsImages = [UIImage]()

    @IBOutlet weak var addEventsButton: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()

    adminAuth()
    eventsRef = Database.database().reference()

    tableView.reloadData()

    tableView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi)

    tableView.delegate = self
    tableView.dataSource = self

    eventsDatabaseHandle = eventsRef?.child("Church Events").observe(.childAdded, with: { (snaphot) in

    let eventPost = snaphot.value as! [String: Any]


    self.eventTimestamps.append(eventPost["eventdate"] as! String)


    self.eventsTitles.append(eventPost["eventtitle"] as! String)

    self.eventsLocations.append(eventPost["eventlocation"] as! String)

    let task = URLSession.shared.dataTask(with: URL(string: eventPost["ImageUrl"] as! String)!) {(data, response, error) in

    if let image: UIImage = UIImage(data: data!) {
    self.eventsImages.append(image)
            }
        }
        self.tableView.reloadData()
        task.resume()

        })
}


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

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

    let image = eventsImages[indexPath.row]

        cell.flyerImages.image! = image

        cell.eventTitle.text! = eventsTitles[indexPath.row]

        cell.eventDate.text! =  eventTimestamps[indexPath.row]

        cell.eventLocation.text! = eventsLocations[indexPath.row]


        cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)

        tableView.reloadData()

        return cell
    }


    func adminAuth() {

        if (Auth.auth().currentUser!.displayName != "Neil Leon")  {
            self.addEventsButton.tintColor = UIColor.clear
            self.addEventsButton.isEnabled = false

        }
        else{

            self.addEventsButton.isEnabled = true
        }
    }
}

image of empty tableview

enter image description here]

Upvotes: 0

Views: 132

Answers (1)

Scriptable
Scriptable

Reputation: 19750

So the code below is not tested as I don't have firebase setup currently.

However, observing childAdded... the documentation says it will pass all of the current records in the database at first and will then just post new additions. So all you need to do is loop through them, setup your tableView data source and reload the table.

Rather than use multiple arrays for values I've created an array of ChurchEvent objects instead.

struct ChurchEvents {
   let title: String
   let location: String?
   let date: Date?
   let imageUrlString: String?

   init(dict: [String: Any]) {
      self.title = dict["title"] as String
      self.location = dict["location"] as? String
      // etc 
   }
}

var events = [ChurchEvents]()

eventsDatabaseHandle = eventsRef?.child("Church Events").observe(.childAdded, with: { snapshot in
     let list = snapshot.value as? [[String : AnyObject]]
     let newEvents = list.map { ChurchEvent(dict: $0) } 
     events.append(newEvents)
     tableView.reloadData()
}

Other improvements you could make:

class EventsTableViewCell: UICollectionViewCell {

   func configure(with event: ChurchEvent {
      eventDate.text = event.date
      eventTitle.text = event.title
      eventLocation.text = event.location
      // etc
   }
}

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

    let event = events[indexPath.row]
    cell.configure(with: event)
    return cell
}

Upvotes: 1

Related Questions