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:

  • UNRESOLVED: Protocol “https” not supported or disabled in libcurl
  • Firebase QueryOrderedByChild along with EqualToValue and StartingAtValue Combination
  • Firebase observe with type .childAdded retrieves all my information every time. Please assist
  • Firebase Value and ChildAdded (further explanation needed)
  • FIREBASE Database - Storing Unique Key to child node(Swift/IOS)
  • How to create a function that will eventually return some data and caller must wait
  • {
    "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:

    {
     "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

    messages
      -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}) {
          self.usersArray.removeAtIndex(index)
          self.usersTableView.reloadData()
      }
    }
    

    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
            print(snapshot)
    
            // 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)
            print(index2)
    
            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
    }