1

I want to update Recyclerview in realtime when a document is added or removed from firestore. I am using this logic in Kotlin:

        for (doc in docs!!.documentChanges) {
            val classElement: FireClassModel=doc.document.toObject(FireClassModel::class.java)

            if (doc.type == DocumentChange.Type.ADDED) {
                adapterList.add(classElement)

            } else if(doc.type == DocumentChange.Type.REMOVED){
                adapterList.remove(classElement)
            }
            adapter.notifyDataSetChanged()
        }

Its working fine when document is added but it does not work when data is removed. It has no error but it doesn't update in real-time. It only updates when I restart the Application.

Updated

FireClassModel:

class FireClassModel {

    var classID: String = ""
    var className: String = ""


}

I tried this classesList.contains(classElement) and it returns false. It means I am unable to compare objects in my ArrayList.

Shahzad Akram
  • 4,586
  • 6
  • 32
  • 65

2 Answers2

1

Finally I have solved the issue. The issue was, I am not getting the right object.

I just replaced adapterList.remove(classElement) with following:

            for (cls in adapterList) {
                if (cls.classID == doc.document.id) {
                    adapterList.remove(cls)
                }
            }

Thanks to @Markus

Shahzad Akram
  • 4,586
  • 6
  • 32
  • 65
0

Your code looks fine, but it seems that the element that you are trying to remove from the list cannot be found there.

adapterList.remove(classElement)

When removing an element from a list using remove(o: Object): Boolean the first matching element from the list will be removed. A matching element is an element where the equals method returns true.

listElement == elementToRemove // Kotlin
listElement.equals(elementToRemove); // Java

By default (that means if you do not override equals) objects will only be equal, if they share the same location in memory. In your example the element in the list sits at a different location than the element that you create from Firestore in your document change listener.

The solution depends on your FireClassModel. Looking at multiple FireClassModel objects, how would you decide which two of them are equal? Maybe they'll have the same id? Then override the equals method (and per contract also hashCode) and compare the fields that make two objects identical. For an id, the solution could look like that (generated by Android Studio):

class FireClassModel(val id: Int) {

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as FireClassModel

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id
    }
}

After that comparing two FireClassModel objects with the same ID will return true. Without overriding the equals method that would not be the case (unless you comparing an object to itself).

More about equals can be found on Stackoverflow and in the Java documentation.

Markus Penguin
  • 1,581
  • 12
  • 19
  • Bro thanks, now I am getting your point, as you mentioned I tried this `classesList.contains(classElement)` and it returns false. I have added some more info in my question please have a look. – Shahzad Akram Sep 25 '18 at 14:31