How to pull users from database and list them in a table view using firebase?

I’m using firebase to make an iOS app. I want to retrieve all the users on my database and display their name and profile picture in a table view. Here is my code for my TableViewCell:

import UIKit
import FirebaseDatabase
import FirebaseAuth
import SDWebImage

class HomeTableViewCell: UITableViewCell {


    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var profileImageView: UIImageView!
    @IBOutlet weak var likeImageView: UIImageView!
    @IBOutlet weak var messageImageView: UIImageView!
    @IBOutlet weak var likeCountButton: UIButton!

    var homeVC: HomeViewController?
    var postReference: DatabaseReference!

    var post: UserFile?{
        didSet {
            updateView()
        }
    }

    var user: UserFile? {
        didSet {
            updateUserInfo()
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        nameLabel.text = ""

        let berryTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleLikeTap))

        likeImageView.addGestureRecognizer(berryTapGesture)
        likeImageView.isUserInteractionEnabled = true

    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

    func updateView() {
        if let photoURL = post?.picURL {
            profileImageView.sd_setImage(with: URL(string: photoURL))
        }

        API.Post.REF_POSTS.child(post!.id!).observeSingleEvent(of: .value, with: { postSnapshot in
            if let postDictionary = postSnapshot.value as? [String:Any] {
                let post = UserFile.transformPost(postDictionary: postDictionary, key: postSnapshot.key)
                self.updateLike(post: post)
            }
        })
        API.Post.REF_POSTS.child(post!.id!).observe(.childChanged, with: { snapshot in
            if let value = snapshot.value as? Int {
                self.likeCountButton.setTitle("\(value) berries", for: .normal)
            }
        })
    }

    func updateLike(post: UserFile) {
        let imageName = post.berries == nil || !post.isBerried! ? "berry" : "berrySelected"
        likeImageView.image = UIImage(named: imageName)

        // display a message for berries
        guard let count = post.berryCount else {
            return
        }

        if count != 0 {
            likeCountButton.setTitle("\(count) berries", for: .normal)
        } else if post.berryCount == 0 {
            likeCountButton.setTitle("Be the first to Like this", for: .normal)
        }
    }

    func incrementberries(forReference ref: DatabaseReference) {
        ref.runTransactionBlock({ (currentData: MutableData) -> TransactionResult in
            if var post = currentData.value as? [String : AnyObject], let uid = Auth.auth().currentUser?.uid {
                var berries: Dictionary<String, Bool>
                berries = post["berries"] as? [String : Bool] ?? [:]
                var likeCount = post["berryCount"] as? Int ?? 0
                if let _ = berries[uid] {
                    // Unlike the post and remove self from stars
                    likeCount -= 1
                    berries.removeValue(forKey: uid)
                } else {
                    // Like the post and add self to stars
                    likeCount += 1
                    berries[uid] = true
                }
                post["berryCount"] = likeCount as AnyObject?
                post["berries"] = berries as AnyObject?

                currentData.value = post

                return TransactionResult.success(withValue: currentData)
            }
            return TransactionResult.success(withValue: currentData)
        }) { (error, committed, snapshot) in
            if let error = error {
                print(error.localizedDescription)
            }

            if let postDictionary = snapshot?.value as? [String:Any] {
                let post = UserFile.transformPost(postDictionary: postDictionary, key: snapshot!.key)
                self.updateLike(post: post)
            }
        }
    }

    func handleLikeTap() {
        postReference = API.Post.REF_POSTS.child(post!.id!)
        incrementberries(forReference: postReference)
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        profileImageView.image = UIImage(named: "industribune-default-no-profile-pic")
    }

    func updateUserInfo() {
        nameLabel.text = user?.username
        if let photoURL = user?.profileImageURL {
            profileImageView.sd_setImage(with: URL(string: photoURL), placeholderImage: UIImage(named: "industribune-default-no-profile-pic"))
        }
    }


}

I am displaying this cell on my HomeViewController:

  • How to Load large HTML string in WebView with LoadHTMLString method?
  • iOS equivalent to Android Service?
  • iOS app freezes when loading custom info window for marker on Google Maps
  • + called within transaction
  • Updating MKannotation image without flashing
  • What is a long-term method I can use to uniquely identify an iOS device?
  • import UIKit
    import FirebaseAuth
    import FirebaseDatabase
    import FirebaseStorage
    import Firebase
    
    class HomeViewController: UIViewController {
    
    
        @IBOutlet weak var tableView: UITableView!
        @IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
    
        var posts = [UserFile]()
        var users = [UserFile]()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // for performance set an estimated row height
            tableView.estimatedRowHeight = 1
            // but also request to dynamically adjust to content using AutoLayout
            tableView.rowHeight = UITableViewAutomaticDimension
    
            //tableView.delegate = self
            tableView.dataSource = self
    
            loadPosts()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func loadPosts() {
            activityIndicatorView.startAnimating()
    
            API.User.observePosts { (newPost) in
                guard let userID = newPost.uid else { return }
                self.fetchUser(uid: userID, completed: {
                    // append the new Post and Reload after the user
                    // has been cached
                    self.posts.append(newPost)
                    self.activityIndicatorView.stopAnimating()
                    self.tableView.reloadData()
                })
            }
        }
    
        func fetchUser(uid: String, completed: @escaping () -> Void) {
    
            API.User.observeUser(withID: uid) { user in
                self.users.append(user)
    
                completed()
            }
        }
    
    
    }
    
    extension HomeViewController: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return posts.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
    
            cell.post = posts[indexPath.row]
            cell.user = users[indexPath.row]
            cell.homeVC = self
    
            return cell
        }
    
    }
    

    I have a lot of craziness going on in my project so let me know if you have any questions and what I’m doing wrong. If it’s too complicated to understand I’m ready to erase everything and start over too.

    And I do honestly think that I followed all the guidelines to ask a question so don’t like shut this question down or something.

    Solutions Collect From Internet About “How to pull users from database and list them in a table view using firebase?”

    That’s a lot of code. Try this super reduced example. For this, the users node only stores the name as a child node but it could also have an image, email, address, etc.

    Example users node

    users
      uid_0:
         name: "Bert"
      uid_1:
         name: "Ernie"
    

    and some code

    var usersArray = [ [String: Any] ]()  //an array of dictionaries.
    
    class ViewController: UIViewController {
        //set up firebase references here
       override func viewDidLoad() {
            super.viewDidLoad()
    
            let usersRef = self.ref.child("users")
            usersRef.observeSingleEvent(of: .value, with: { snapshot in
             for child in snapshot.children {
                  let snap = child as! DataSnapshot
                  let userDict = snap.value as! [String: Any]
                  self.usersArray.append(userDict)
             }
             self.tableView.reloadData()
       })
    

    and the tableView delegate methods

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.usersArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
    
        let userDict = self.usersArray[indexPath.row]
        cell.text = userDict["name"] as! String
        //cell.imge = userDict["image"] etc etc
    
        return cell
    }
    

    Now… that all being said. This is the perfect use for an array of UserClass objects instead of the dictionaries.

    Here’s a starting point….

    class UserClass {
       var name = ""
       var image = ""
    
       func init(snap: DataSnapshot) {
         //populate the vars from the snapshot
       }
    }
    
    var userClassArray = [UserClass]()
    

    Don’t copy and paste this as there are probably typos but it should point you in the right direction.