Reputation: 970
I have an error that occurs when I add or delete data from a node in firebase. When the data is added or deleted on firebase I get an array index out of bounds error. My array has two items, but the tableView thinks that there are three items and thus tries to access a value that doesn't exist. I can't figure out how to prevent this. For more context I am using an alertView with a closure that performs the adding or deleting of information in firebase. This alertView is in the didSelectCellAtIndexPath method. The error is occurring in the cellForRowAtIndexPath Method when accessing the array like so user.id = self.bookRequestors[indexPath.row]
Here is some of the code I wrote: `
alertVC.addAction(PMAlertAction(title: "Approve this users request",
style: .default, action: {
print("Book Approved")
let user = User()
user.id = self.bookRequestors[indexPath.row]
var users = self.userInfoArray[indexPath.row]
var bookRef = Database.database().reference().child("books").child("-" + self.bookID)
bookRef.observeSingleEvent(of: .value, with: { (snapshot) in
var tempDict = snapshot.value as! [String:AnyObject]
if tempDict["RequestApproved"] == nil || tempDict["RequestApproved"] as! String == "false"{
//bookRef.updateChildValues(["RequestApproved": "true", "ApprovedRequestor": user.id])
bookRef.updateChildValues(["RequestApproved": "true", "ApprovedRequestor": user.id], withCompletionBlock: { (error, ref) in
let userRef = Database.database().reference().child("users").child(user.id!).child("requestedBooks")
// true meaning this book has been approved for this user
userRef.updateChildValues(["-" + self.bookID:"true"])
})
} else{
print("Already Approved!")
let alertVC = PMAlertController(title: "Sorry?", description: "You Already Approved that book for someone Else", image: UIImage(named: "booksandcoffee.jpg"), style: .alert)
alertVC.addAction(PMAlertAction(title: "Ok", style: .default))
self.present(alertVC, animated: true, completion: nil)
}
})`
EDIT: MORE CODE FOR CONTEXT
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "people", for: indexPath) as! RequestTableViewCell
// Configure the cell...
var users = self.userInfoArray[indexPath.row]
var myName = users["name"]
var myPic = users["profileImageUrl"]
let user = User()
print("This is a count: \(self.bookRequestors.count)")
print ("the index is: \(indexPath)")
//This is the array throwing the error, but this array is populated from the previous view and is not modified afterwards.
user.id = self.bookRequestors[indexPath.row]
cell.userImage?.setRounded()
cell.userImage.clipsToBounds = true
let processor = RoundCornerImageProcessor(cornerRadius: 100)
DispatchQueue.main.async {
cell.userImage.loadImageUsingCacheWithUrlString(myPic as! String)
}
cell.userName.text = myName as! String
if user.id == approvedRequestorID{
cell.wasApproved.image = UIImage(named: "icons8-checked_filled.png")
cell.approvedLabel.text = "You approved to swap with: "
}
cell.backgroundColor = .clear
return cell
}
EDIT II : Here are my numberofSections and numberofRowsPerSection Methods
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return userInfoArray.count
}
EDIT III: Function where userInfoArray is updated.
func grabUsers(){
//print(bookRequestors)
for requests in bookRequestors{
let usersRef = Database.database().reference().child("users").child(requests)
usersRef.observe(.value, with: { (snapshot) in
var myDict:[String: AnyObject] = [:]
myDict = snapshot.value as! [String:AnyObject]
self.userInfoArray.append(myDict)
self.tableView.reloadData()
})
}
}
Upvotes: 1
Views: 228
Reputation: 16327
Its hard to tell what exactly is going on without seeing your code, but here is my best guess:
You are backing your cells with self.bookRequestors
which you say is a static array assigned by the previous VC.
However you are using userInfoArray.count
to back the number of rows in the tableView, and this value changes in your usersRef.observe
method.
Specifically you are appending to userInfoArray
; so userInfoArray.count
strictly increases.
Therefore if the two arrays statrt at the same size, and the one that determines the count is getting bigger but the one you are indexing into is always the same size, then eventually you will index out of bounds.
Back the number of rows by the data you are actually showing in the cell.
Upvotes: 1