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 DocumentSnapshotLiveData( private val docRef: DocumentReference) : LiveData<Resource<DocumentSnapshot>>(), EventListener<DocumentSnapshot> { private var registration: ListenerRegistration? = null override fun onEvent(snapshot: DocumentSnapshot?, e: FirebaseFirestoreException?) { // setValue value = if (e != null) { Resource(e) } else { Resource(snapshot!!) } } override fun onActive() { super.onActive() registration = docRef.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 getLiveData(val userId: String): DocumentSnapshotLiveData { val docRef = firestore.collection("users").document(userId) return DocumentSnapshotLiveData(docRef)}
val userId = ...getLiveData(userId).observe(owner, Observer { result -> if (result.isSuccessful) { // do something val doc = result.data() } else { Timber.e(result.error()) }})
NOTE: Refer to Firestore addSnapshotListener with LifecycleOwner.
Kotlin Extension
fun DocumentReference.asSnapshotLiveData(): DocumentSnapshotLiveData { return DocumentSnapshotLiveData(this)}
fun getLiveData(val userId: String): DocumentSnapshotLiveData { return firestore.collection("users").document(userId) .asSnapshotLiveData()}
References: