Victor Victor -4 years ago 97
Swift Question

Can not remove .childRemoved from external Firebase server due to expected Int instead of String

I'm a newbie in Swift -please have mercy- with my code, I can not remove .childRemoved from external Firebase server due to expected Int instead of Stringand can not figure out how to remove from my tableview a message that I'm erasing from the external Firebase

import UIKit
import Firebase

class FCViewController: UIViewController, UINavigationControllerDelegate {

var ref: FIRDatabaseReference!
var messages: [FIRDataSnapshot]! = []

func configureDatabase() {

ref = FIRDatabase.database().reference()

ref.child("messages").observe(.childRemoved, with: { (snapshot) in

// MY PROBLEM 1: can not remove this chat with such identifier from the external Firebase server because an Int is expected instead of an String
self.messages.remove(at: snapshot.key)

// MY PROBLEM 2: when solving PROBLEM 1, table does not reload from Firebase like this, check on the comments the link for the answer to this:
// reload table to featch data from Firebase
self.messagesTable.reloadData()



}, withCancel: nil)

}

}


snapshot.key

prints: -KflJWAyY3KSyyN8RA5U


self.messages prints:

[Snap (-KflJVkAYLaoEiFPD86N) {
name = "user 1";
text = fadsfd;
timestamp = "2017-03-21 14:42:45 +0000";
},
Snap (-KflJWAyY3KSyyN8RA5U) {
name = "user 1";
text = adsfasdf;
timestamp = "2017-03-21 14:42:45 +0000";
}]


Thank you!

Answer Source

var messages: [FIRDataSnapshot]! = []

is an array of snapshots and you are trying to remove it via a string (snapshot.key is a string)

self.messages.remove(at: snapshot.key)

and Swift is expecting at: to be an integer index within the array.

I would suggest not doing this as the objects you stored in the array will be different (object id's) than the object that's referenced when it's removed.

You will be much better off working with an array of dictionaries or even for example, MessageClass objects, that have been populated with the data from a Firebase Snapshot with the key as one of it's parameters.

Here's some code covering all the bases

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

var messagesArray = [MessageClass]()

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
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download