Firebase ios snapshot returning null for .childRemoved

I just started working with Firebase with Swift and have a example messages node. I add messages children that hold the text and username, etc. I have security rules set to be authenticated for each .write and .read. I created a observer to watch for this even and it is firing but the snapshot it returns is null. The reason I need the snapshot data is so I can remove that exact message from the client side.

Data Node Structure:

  • Firebase Retrieving Data in Swift
  • Follower counter not updating node in firebase
  • How can i access firebase variable outside firebase function
  • Firebase: Can I use Facebook's new Account Kit to authenticate app users?
  • The request was denied by service delegate (SBMainWorkspace)
  • “Copy this file to your authentication server” - Firebase Custom auth
  • {
    "messages" : {
        "-KcM3SlAQXfjCz01waXF" : {
        "name" : "mgardner1994",
        "text" : "test23"
        "-KcM3UKA_U7n2YwhlFeB" : {
        "name" : "mgardner1994",
        "text" : "test4"
        "-KcMB_8Ec74HIQGL9adt" : {
        "name" : "mitchell_maler",
        "text" : "test5"
        "-KcOC08kLUO-cEWLeICG" : {
        "name" : "mitchell_maler",
        "text" : "hello"
        "-KcOC6ZWT6gyVi6pxGF8" : {
        "name" : "mitchell_maler",
        "text" : "test"


     "rules": {
       "messages": {
         ".read": "auth != null",
         ".write": "auth != null"

    Swift Code:

    _refHandleDel = ref.child("messages").observe(.childRemoved, with: { (snapshot) -> Void in
        // TODO: Why is snapshot returning nil
        let index = self.messages.index(of: snapshot)
        self.messages.remove(at: index!)
        self.messagesTable.deleteRows(at: [IndexPath(row: index! , section: 0)], with: .automatic)

    Edit: Added data structure to text instead of an image.

    2 Solutions Collect From Internet About “Firebase ios snapshot returning null for .childRemoved”

    You may want to go about it in another way:

    Each snapshot (or the child snapshots) will have a key and that’s what you should be looking up in your array (table, dataSource etc)

    In other words, when the messages are initially loaded (into a dataSource for example) they will be in a key:value pair of

      -KcM3SlAQXfjCz01waXF (the key)
        name : "mgardner1994", (the values which are a dictionary)
        text : "test23"

    Ideally you will end up with an array of those key value pairs

    a[0] = key:value = -KcM3SlAQXfjCz01waXF: dictionary of children
    a[1] = key:value = -KcM3UKA_U7n2YwhlFeB: dictionary of children

    Note the above is dictionary but it could be a UserClass or ItemsClass

    a[0] = aUser (UserClass)
    a[1] = aUser (UserClass)

    When your app receives a remove event, it will be passed the key:value pair as the snapshot. We don’t care about the value but we do care about the key as you can then find the index of that item in the array and remove it. (via ObjC NSPredicate to find the match) or… something like this in Swift if you are using a UserClass for example

    func handleChildRemoved(_ snapshot: FDataSnapshot! ) {
      let key = snapshot.key
      if let index = self.usersArray.indexOf({$0.firebaseKey == key}) {

    In this example, I have UserClass

    class UserClass {
       firebaseKey = ""
       userName = ""

    I was able to get around the issue by creating a lookup function that looks for the key. I am still unsure why the index(of) method isn’t working but will keep digging.

    _refHandleDel = ref.child("messages").observe(.childRemoved) { (snapshot: FIRDataSnapshot!) in
            // Never finds the object and returns nil
            let index = self.messages.index(of: snapshot)
            print(index ?? "no")
            // using the workaround method it finds the index using the key
            let index2 = self.indexOfSnapshotInArray(snapshot: snapshot, snapshotArray: self.messages)
            if (index2 != -1) {
            self.messages.remove(at: index2)
            self.messagesTable.deleteRows(at: [IndexPath(row: index2 , section: 0)], with: .automatic)
            } else {
                print("Could not find message in array.")
    func indexOfSnapshotInArray(snapshot: FIRDataSnapshot, snapshotArray: [FIRDataSnapshot]) -> Int {
        var index = 0
        for snap in snapshotArray {
            if (snapshot.key == snap.key) {
                return index
            index += 1
        return -1