0

I have just started on Firebase.

Here is the JSON on Firebase :

{
  "messages" : {
    "-K2ib4H77rj0LYewF7dP" : {
      "name" : "anonymous",
      "text" : "Hello"
    },
    "-K2ib62mjHh34CAUbide" : {
      "name" : "anonymous",
      "text" : "I am fine"
    },
    "Test" : {
      "name" : "test111",
      "text" : "text22"
    }
  }
}  

In Swift, I am observing when an item is added/removed on server, it should reflect in the app. Adding a record works fine. But for removing, I am not sure how to delete the item from the array based on index. Using indexOf returns a address (I guess array won't remove the object without mapping).

This is the incorrect code I have tried and does not work :

_refHandle = self.ref.child("messages").observe(.childRemoved, with: { [weak self] (snapshot) -> Void in
        guard let strongSelf = self else { return } 

        let values = snapshot.value as? NSDictionary
        let indexToBeRemoved = strongSelf.messages.index(where: {
            let valuesFilter = $0.value as? NSDictionary
            valuesFilter!["name"] as! NSString === values!["name"] as! NSString
            return true
        })
        print(indexToBeRemoved)
        strongSelf.messages.remove(at: indexToBeRemoved!)  
        strongSelf.clientTable.deleteRows(at: [IndexPath(row: indexToBeRemoved!, section: 0)], with: .automatic)    
    })  

indexToBeRemoved comes out to be 0.

I also tried to simply remove the object using this answer but it returned an address.

Expected result :

Get the index of DataSnapshot object which is to be removed

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Nitish
  • 13,845
  • 28
  • 135
  • 263
  • Try to use functions that has `withPreviousSiblingWithKey`, something like `func observeSingleEvent(of eventType: DataEventType, andPreviousSiblingKeyWith block: @escaping (DataSnapshot, String?) -> Void)`, so you could get the key of the previous sibling, then it is easier to find the index of this key in your model array. (You can make it an array of tuples of "key, value", don't use dictionary, to preserve the arrangement) – user9335240 Feb 22 '18 at 12:30
  • @user9335240 : How to use that along with childRemoved ? – Nitish Feb 22 '18 at 12:45
  • To be able to identify the child to be removed you should compare its **key*, which is guaranteed to be unique. This means you need to store the key for each child into the array in `childAdded`, so that you can then look up that child's entry in the array when you get `childRemoved`. – Frank van Puffelen Feb 22 '18 at 14:38

1 Answers1

1

So this is what worked for me :

_refHandle = self.ref.child("messages").observe(.childRemoved, with: { [weak self] (snapshot) -> Void in
        guard let strongSelf = self else { return }

        let values = snapshot.value as? NSDictionary
        let indexToBeRemoved = strongSelf.messages.index(where: {
            let valuesFilter = $0.value as? NSDictionary
            return valuesFilter!["name"] as! NSString === values!["name"] as! NSString
        })

        print(indexToBeRemoved)
        strongSelf.messages.remove(at: indexToBeRemoved!)
        strongSelf.clientTable.deleteRows(at: [IndexPath(row: indexToBeRemoved!, section: 0)], with: .automatic)
    })  

I returned the result of the comparison to the index.

But I believe this is not the best way to accomplish this. Since, in JSON, there might not be a unique key (I am taking name for comparison).
I would really like to see a better solution for this.

Nitish
  • 13,845
  • 28
  • 135
  • 263