Binayak Pandey
Binayak Pandey

Reputation: 89

'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 sections after the update'

I am making an iOS app but I keep getting this error:

'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 sections after the update'

I have researched this question for 2 days now but I don't know what's wrong. I am putting my code down below.

import UIKit
import FirebaseDatabase
import FirebaseAuth

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

var databaseRef = Database.database().reference()
var loggedInUser:AnyObject?
var loggedInUserData:NSDictionary?

@IBOutlet weak var aivLoading: UIActivityIndicatorView!

@IBOutlet weak var homeTableView: UITableView!

var posts = [NSDictionary]()

override func viewDidLoad() {
    super.viewDidLoad()
    self.loggedInUser = Auth.auth().currentUser

    self.databaseRef.child("users").child(self.loggedInUser!.uid).observeSingleEvent(of: .value) { (snapshot: DataSnapshot) in

        self.loggedInUserData = snapshot.value as? NSDictionary
        self.databaseRef.child("posts").child(self.loggedInUser!.uid).observe(.childAdded, with: { (snapshot: DataSnapshot) in

            self.posts.insert(snapshot.value as! NSDictionary, at: 0)
            self.homeTableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.automatic)
            self.aivLoading.stopAnimating()
        }){(error) in
            ProgressHUD.showError("There was an error, try again")
        }
    }

    self.homeTableView.rowHeight = UITableViewAutomaticDimension
    self.homeTableView.estimatedRowHeight = 140

}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: HomeTableViewCell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
    let post = posts[(self.posts.count-1) - (indexPath.row)]["text"] as! String

    cell.configure("Anonymous", post: post)
    return cell
}

}

In my code, it refers to a dequeueReusableCell, with the identifier HomeTableViewCell, which is a Swift file. Here is the code for that Swift file:

import UIKit
import FirebaseDatabase
import Firebase
import FirebaseAuth


class HomeTableViewCell: UITableViewCell {


    @IBOutlet weak var nameConstant: UILabel!
    @IBOutlet weak var post: UITextView!


    override open func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    open func configure(_ nameConstant: String, post: String)  {
        self.post.text = post
        self.nameConstant.text = "Anonymous"
    }

}

I know there are similar questions to mine but a lot of those are in Objective-C. I've looked at the Swift ones too but they don't help.

If anyone has any ideas to fix this that would be great. Thanks in advance!

Upvotes: 1

Views: 833

Answers (1)

Eli Kohen
Eli Kohen

Reputation: 521

In your code you're always returning 1 for number of rows. But i guess you should be returning posts.count right? Every time you insertRows(at:... the table checks consistency through the delegate. There's also something weird, you're appending to your list (self.posts.append(snapshot.value as! NSDictionary)) but then you're inserting row 0-0?, I'll assume you want to insert new post to the top. Moreover if you have just one section, you don't need to implement the method.

So here's the code (I'm assuming the firebase and cell configuration code is correct):

import UIKit
import FirebaseDatabase
import FirebaseAuth

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

var databaseRef = Database.database().reference()
var loggedInUser:AnyObject?
var loggedInUserData:NSDictionary?

@IBOutlet weak var aivLoading: UIActivityIndicatorView!

@IBOutlet weak var homeTableView: UITableView!

var posts = [NSDictionary]()

override func viewDidLoad() {
    super.viewDidLoad()
    self.loggedInUser = Auth.auth().currentUser

    self.databaseRef.child("users").child(self.loggedInUser!.uid).observeSingleEvent(of: .value) { (snapshot: DataSnapshot) in

        self.loggedInUserData = snapshot.value as? NSDictionary
        self.databaseRef.child("posts").child(self.loggedInUser!.uid).observe(.childAdded, with: { (snapshot: DataSnapshot) in

            self.posts.insert(snapshot.value as! NSDictionary, at: 0)
            self.homeTableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.automatic)
            self.aivLoading.stopAnimating()
        }){(error) in
            ProgressHUD.showError("There was an error, try again")
        }
    }

    self.homeTableView.rowHeight = UITableViewAutomaticDimension
    self.homeTableView.estimatedRowHeight = 140

}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: HomeTableViewCell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
    let post = posts[(self.posts.count-1) - (indexPath.row)]["text"] as! String

    cell.configure("Anonymous", post: post)
    return cell
}

}

I hope it fixes your problem ;)

Upvotes: 1

Related Questions