0

I'm having trouble with loading the table view. The moment I call self.messagesTable.reloadData() my local tableView does not reload the data deleted from a external Firebase server.

These two are my handlers for the observer:

fileprivate var _refHandle: FIRDatabaseHandle! 
fileprivate var _refHandleDel: FIRDatabaseHandle!

Outlet

@IBOutlet weak var messagesTable: UITableView!

Code in FCViewController:

var ref: FIRDatabaseReference!
var messages: [FIRDataSnapshot]! = []
var messageClass = [Message]()
var messageDictionary = [String: Message]()

func configureDatabase() {

        // configure database to sync messages and connect it to the data base starting at "/"
        ref = FIRDatabase.database().reference()

        // create a listener on what happend on the database
        _refHandle = ref.child("messages").observe(.childAdded) { (snapshot: FIRDataSnapshot!) in
            self.messages.append(snapshot)
            // Animate and scroll the new message loaded
            self.messagesTable.insertRows(at: [IndexPath(row: self.messages.count - 1, section: 0)], with: .automatic)
            self.scrollToBottomMessage()
        }

        _refHandleDel = ref.child("messages").observe(.childRemoved, with: { (snapshot: FIRDataSnapshot!) in

            self.messageDictionary.removeValue(forKey: snapshot.key)

            // MY PROBLEM IS HERE: The table does not load properly and does not reloadData from the server after deleting the snapshot.key
            self.messagesTable.reloadData()


    }, withCancel: nil)
    }




deinit {
        // set up what needs to be deinitialized when view is no longer being used
        // we remove the observer that is all the time checking for updates in the .observer handler
        ref.child("messages").removeObserver(withHandle: _refHandle)
        ref.child("messages").removeObserver(withHandle: _refHandleDel)

        // we also remove the listener for auth changes when the user registers
        FIRAuth.auth()?.removeStateDidChangeListener(_authHandle)
    }

Scroll Messages Function also inside the FCViewController:

func scrollToBottomMessage() {
    if messages.count == 0 { return }
    let bottomMessageIndex = IndexPath(row: messagesTable.numberOfRows(inSection: 0) - 1, section: 0)
    messagesTable.scrollToRow(at: bottomMessageIndex, at: .bottom, animated: true)

}

Message Class Object in a separate .swift file courtesy of @Jay

class Message: NSObject {

class MessageClass {
    var key = ""
    var name = ""
    var text = ""
    var timestamp = ""
}

var messagesArray = [MessageClass]()
let ref = FIRDatabase.database().reference()

func readInAllMessages() {
    let messagesRef = ref.child("messages")
    messagesRef.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children {
            let snap = child as! FIRDataSnapshot
            let msg = self.snapToMsgClass(child: snap)
            self.messagesArray.append(msg)
        }
    })
}

func addRemoveObserver() {
    let messagesRef = ref.child("messages")
    messagesRef.observe(.childRemoved, with: { snapshot in
        let keyToRemove = snapshot.key

        if let i = self.messagesArray.index(where: { $0.key == keyToRemove }) {
            self.messagesArray.remove(at: i)
        }
    })
}

func snapToMsgClass(child: FIRDataSnapshot) -> MessageClass {
    let dict = child.value as! [String:Any]
    let name = dict["name"] as! String
    let msg = MessageClass()
    msg.name = name
    msg.key = child.key
    return msg
}


}
Victor
  • 164
  • 7
  • The question doesn't make sense. If you call tableView.reloadData(), it's going to iterate over your datasource and populate the tableView with that data. If the data was deleted from the Firebase server (assuming it was removed from the dataSource as well) it would not appear in the tableView - so that's working as intended. What result are you expecting? are you expecting deleted data to appear? – Jay Mar 27 '17 at 17:01
  • Also, tableView.reloadData() does NOT reload anything other than from the dataSource, which is typically an array. i.e it will not load data from Firebase. – Jay Mar 27 '17 at 17:04
  • Oh, and if you look, you're using *self.messageDictionary* to store your message whereas it should be an array as in my example *var messagesArray = [MessageClass]()*. Technically it could be a dictionary but then you loose ordering and it's a little unusual for this type of use case. Finally, this *self.messagesTable.insertRows* is the wrong direction. You need implement a tableView delegate which handles the tableview updates, displaying etc. All you do it insert the new data into the array and then tableView.reloadData() and it takes care of itself. – Jay Mar 27 '17 at 17:06
  • See [UITableView tutorial](http://stackoverflow.com/questions/33234180/uitableview-example-for-swift) – Jay Mar 27 '17 at 17:13

0 Answers0