Roman H
Roman H

Reputation: 251

Save Firebase structure in UITableView Array [Swift 4]

I am new to programming and currently trying to make a newsfeed like app. My goal is it to notice changes in the firebase database through my app and new posts in my table view. Currently I am able to show one post in my tableView. Its only changing though when you reopen the ViewController. One of my problem is that I don't know how to use any other command then obserSingleEvent and I am pretty sure that one of my main mistakes. So my questions are: 1. How do I make the tableView instantly reload when a change appears? 2. how do I display more then one post? (3. how can I show the most recent posts first?)

class ViewController: BaseViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var newsfeedTableView: UITableView!

var ref: DatabaseReference!

var posts = [String]()

override func viewDidLoad() {
    super.viewDidLoad()
    addSlideMenuButton()

    ref = Database.database().reference()

    ref.child("posts").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: { snapshot in

        let newPost = snapshot.value as? String
        self.posts.append(newPost!)
        print("newPost: \(newPost)")
        print("posts: \(self.posts)")
        self.newsfeedTableView.reloadData()
        print("reloadData")
    })

}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "cell")

    cell.textLabel?.text = posts[indexPath.row]
    print("posts in cell: \(posts)")

    return cell
}
}

Database structure

Upvotes: 1

Views: 255

Answers (2)

Galo Torres Sevilla
Galo Torres Sevilla

Reputation: 1575

1) You can implement a function that is constantly observing the data in Firebase for changes and update the array. But be careful with that, it will be consuming memory and also you will get a lot of network usage.

.observe // instead of .observeSingleEvent will do that

Again, it would be better if you add a refresher to the tableView so you fetch the data on demand instead of all the time.

2) Your array is fine. I'll move the call to firebase to another function instead of having it in viewDidLoad().

3) You need to store a timeStamp in firebase to get this functionality. Yes, you can queryOrdered but remember firebase is async. Data will be given as available so it would be better to sort the array depending on the creation timeStamp of each of the items.

Upvotes: 1

Rawand Ahmed Shaswar
Rawand Ahmed Shaswar

Reputation: 2561

You're observing with singleEvent which is wrong for the intended use.

ref.child("posts").observe( .childAdded, with: { snapshot in

    let newPost = snapshot.value as? NSDictionary
    let post_title:String = newPost!["post_title"] as? String ?? "error"
    self.posts.append(post_title)

    print("newPost: \(newPost)")
    print("posts: \(self.posts)")
    self.newsfeedTableView.reloadData()
    print("reloadData")
})

Also, that sorting system won't work for a news app. you can't work with human-provided 1,2,3. could you update it to something like this from now on:

img

(1 - 2) A random-unique generated post ID

PS. It's impossible for Firebase to order your post list with post, post1, post2. So in this case queryOrderedByKey() is useless.

Making the posts 1,2,3 would work for the ordering system

Upvotes: 1

Related Questions