I'm trying to experiment a proper way to convert a complete task into a sealed class easy to read when performing a get request on a document (at this time and I will see later for collections request).
import com.google.android.gms.tasks.Task
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestoreException
import timber.log.Timber
fun <T> Task<DocumentSnapshot?>.toDocumentResult(parser: (documentSnapshotExisting: DocumentSnapshot) -> T): DocumentResult<T>?{
val documentResult: DocumentResult<T> = if(isSuccessful){
val documentSnapshot: DocumentSnapshot = result!!
if(documentSnapshot.exists()){
try {
DocumentResult.Found(parser.invoke(documentSnapshot))
}
catch (e: java.lang.Exception){
DocumentResult.ParserException<T>(documentId = documentSnapshot.id, e = e)
}
}else{
DocumentResult.NotFound(documentSnapshot.id)
}
}else{
DocumentResult.Error(exception!! as FirebaseFirestoreException)
}
documentResult.log()
return documentResult
}
sealed class DocumentResult<T>{
abstract fun log()
class Found<T>(val o: T): DocumentResult<T>() {
override fun log() {
Timber.tag("DocumentResult").w("$o")
}
}
class NotFound<T>(val documentId: String): DocumentResult<T>() {
override fun log() {
Timber.tag("DocumentResult").w("documentId: $documentId doesn't exist")
}
}
class ParserException<T>(val documentId: String, val e: Exception): DocumentResult<T>() {
override fun log() {
Timber.tag("DocumentResult").e("ParserException: ${e.localizedMessage?:e.message?:"error"}, documentId: $documentId")
}
}
class Error<T>(val e: FirebaseFirestoreException): DocumentResult<T>() {
override fun log() {
Timber.tag("DocumentResult").e("FirebaseFirestoreException - code: ${e.code.name}, ${e.localizedMessage?:e.message?:"error"}")
}
}
}
With this snippet, I can do this :
activity.firestore.documentAvailableLanguages().get().addOnCompleteListener { task ->
val documentResult = task.toDocumentResult { AvailableLanguages.toObject(it) }
when(documentResult){
is DocumentResult.Found -> { /* My converted object */ }
is DocumentResult.NotFound -> { /* document not found */}
is DocumentResult.Error-> { /* FirebaseFirestoreException */}
is DocumentResult.ParserException -> { /* Conversion didn't work, exception */ }
}
}
My question is :
1) Can we reasonably ensure that Task.exception is always not null and instance of FirebaseFirestoreException when isSuccessFul is false ?
2) Are we sure that task.result is always not null when task.isSuccessful is true ?
Thanks in advance