Skip to content

Instantly share code, notes, and snippets.

@vitoksmile
Last active June 22, 2019 09:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vitoksmile/c9940b890f3b5654df434fb2baa0c67c to your computer and use it in GitHub Desktop.
Save vitoksmile/c9940b890f3b5654df434fb2baa0c67c to your computer and use it in GitHub Desktop.
Custom LiveData to works with FirebaseFirestore snapshots
import androidx.lifecycle.LiveData
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ListenerRegistration
import com.google.firebase.firestore.QuerySnapshot
/**
* Custom [LiveData] to works with [FirebaseFirestore] snapshots
*
* @param collection The current collection's name
* @param transformer Transform [DocumentSnapshot] to [T]
* @param query Query conditions
*/
class FirestoreLiveData<T : Any>(
private val collection: String,
private val transformer: Transformer<T>,
private val query: (CollectionReference.() -> Query)? = null
) : LiveData<List<T>>() {
interface Transformer<T> {
fun transform(document: DocumentSnapshot): T
}
/**
* Firebase Firestore
*/
private val db by lazy { FirebaseFirestore.getInstance() }
/**
* Snapshot listener
*/
private var listener: ListenerRegistration? = null
override fun onActive() {
subscribe()
}
override fun onInactive() {
unSubscribe()
}
/**
* Subscribe to snapshot updates
*/
private fun subscribe() {
unSubscribe()
listener = db.collection(collection)
.run {
query?.invoke(this) ?: this
}
.addSnapshotListener { querySnapshot, firebaseFirestoreException ->
querySnapshot?.let(this::onSnapshotGot)
}
}
private fun onSnapshotGot(snapshot: QuerySnapshot) {
value = snapshot.documents.mapNotNull {
try {
transformer.transform(it)
} catch (error: Throwable) {
error.printStackTrace()
null
}
}
}
/**
* Unsubscribe from updates
*/
private fun unSubscribe() {
listener?.remove()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment