1

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()
        })

    }

}
13
  • You might want to show your data tree as a picture. Commented Feb 26, 2018 at 1:51
  • @ElTomato , the data is being added and deleted properly in firebase. When I relaunch the app the data is read in correctly and there is no crash. The problem only occurs client side when adding or removing the value. Commented Feb 26, 2018 at 1:52
  • "The problem only occurs client side when adding or removing the value." The cause is pretty much obvious. But you aren't showing all relevant lines of code. Commented Feb 26, 2018 at 1:55
  • I am not understanding how the adding or removing of the data in firebase is causing the problem, when the array itself is not being modified. Nor is the data in the array being modified. But an extra cell is some how being added, not sure how how. When I print out the cell indexPath it returns [0,0], [0,1] when the table is loaded. After I perform the changes in the firebase data base the indexPath returns [0,0], [0,1],[0,2]. Again I am not modifying the array or the data contained in the array that is throwing the error. Commented Feb 26, 2018 at 2:02
  • You need to show your numberOfSections and numberOfRowsInSection methods. Commented Feb 26, 2018 at 2:29

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.