Extend LiveData
- LiveData in active state when in Lifecycle.State.STARTED or Lifecyle.State.RESUMED state. I assume this means LiveData is not active when after
Activity.onPause
orActivity.onStop
. - Lifecycle.State.STARTED: equivelant to Activity's after onStart and before onPause
- Lifecyle.State.RESUMED: equivelant to Activity's after onResume.
- onActive: when the LiveData object has an active observer
- onInactive: when the LiveData object doesn't have any active observers
- setValue: updates the value of the LiveData instance and notifies any active observers about the change.
class QuerySnapshotLiveData(private val query: Query) : LiveData<Resource<QuerySnapshot>>(), EventListener<QuerySnapshot> { private var registration: ListenerRegistration? = null override fun onEvent(snapshots: QuerySnapshot?, e: FirebaseFirestoreException?) { value = if (e != null) { Resource(e) } else { Resource(snapshots!!) } } override fun onActive() { super.onActive() registration = query.addSnapshotListener(this) } override fun onInactive() { super.onInactive() registration?.also { it.remove() registration = null } }}
class Resource<T> private constructor( private val data: T?, private val error: Exception?) { val isSuccessful: Boolean get() = data != null && error == null constructor(data: T) : this(data, null) constructor(exception: Exception) : this(null, exception) fun data(): T { if (error != null) { throw IllegalStateException("Check isSuccessful first: call error() instead.") } return data!! } fun error(): Exception { if (data != null) { throw IllegalStateException("Check isSuccessful first: call data() instead.") } return error!! }}
Usage
fun fetchLiveData(): QuerySnapshotLiveData { val query = firestore.collection("users") .whereEqualTo("is_active", true) return QuerySnapshotLiveData(query)}
fetchLiveData().observe(owner, Observer { result -> if (result.isSuccessful) { // do something val query = result.data() } else { Timber.e(result.error()) }})
Add Kotlin Extension
fun Query.asSnapshotLiveData(): QuerySnapshotLiveData { return QuerySnapshotLiveData(this)}
fun fetchLiveData(): QuerySnapshotLiveData { return firestore.collection("users") .whereEqualTo("is_active", true) .asSnapshotLiveData()}
NOTE: Refer to Firestore addSnapshotListener with LifecycleOwner.
References: