Inside the onCreateView() method of a fragment, I am attaching 3 valueEventListeners to different, mutually exclusive locations at firebase databse. Whenever the data at the reference is updated, they are triggered asynchronously. My sample code looks like this:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
listner1 = ref1.addCustomValueEventListener {
list1.clear()
// do some operation and populate list1
rewriteMainData()
}
listner2 = ref2.addCustomValueEventListener {
list2.clear()
// do some operation and populate list2
rewriteMainData()
}
listner3 = ref3.addCustomValueEventListener {
list3.clear()
// do some operation and populate list3
rewriteMainData()
}
}
private fun rewriteMainData() {
mainList.clear()
mainDbReference.addCustomListenerForSingleValueEvent {
// compare the values present here with values in list1, list2, list3
// populate mainList with appropriate values
// notifyAdapterDataSetChanged
}
return
}
// EXTENSION FUNCTION
internal inline fun DatabaseReference.addCustomValueEventListener(crossinline onDataChange: (DataSnapshot) -> Unit) =
addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
onDataChange(snapshot)
}
override fun onCancelled(error: DatabaseError) {
Log.e(TAG, "onCancelled: ", error.toException())
}
})
In this example however, if one listener is triggered soon after the another, then rewriteMainData() will be invoked twice. At that time, mainList will be wrote simultaneously by two callbacks. One way to solve this is to use an instance of ReentrantLock to avoid simultaneous writes. But this makes latest invoke to wait till its previous invoke is completed, which is redundant since all data will be cleared and rewritten.
Hence is there any way to know when rewriteMainData() is invoked and if it is already running, then to just abort and restart the function with updated lists?