Firestore (Kotlin) правильный способ конвертировать завершенную задачу в запечатанный класс при выполнении запроса документа - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь поэкспериментировать, как правильно преобразовать завершенную задачу в запечатанный класс, легко читаемый при выполнении запроса get для документа (в данный момент и позже я увижу запрос сбора).

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"}")
        }
    }
}

С помощью этого фрагмента я могу сделать следующее:

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 */ }
    }
}

Мой вопрос:

1) Можем ли мы разумно убедиться, что Task.exception всегда не равно NULL и экземплярFirebaseFirestoreException, когда isSuccessFul имеет значение false?

2) Мы уверены, что task.result всегда не равен нулю, когда task.isSuccessful имеет значение true?

Заранее спасибо

1 Ответ

0 голосов
/ 28 января 2019

Обратите внимание, что для обоих вопросов задание является «успешным», когда работа, представленная заданием, завершена, как и ожидалось, без ошибок.С другой стороны, Задача является «завершенной», когда работа, представленная Задачей, завершена, независимо от ее «успеха» или «неудачи».Может быть, а может быть, а может и не быть ошибкой, вам придется проверить это.

Уже успешно выполненное задание возвращает DocumentSnapshot, которое никогда не будет иметь значениеnull.Если запрошенный документ не существует, вы получите пустой объект DocumentSnapshot, а не null.Это также означает, что если вы будете вызывать exists():

documentSnapshot.exists() //Will returns false

И если вы вызываете getData() метод:

documentSnapshot.getData() //An exception will be thrown

Если Такс не «успешен»,Исключение, выдаваемое task.getException(), является экземпляром FirebaseFirestoreException.Обратите внимание, что метод Task * getException () :

Возвращает исключение, которое вызвало сбой Задачи.Возвращает ноль, если Задача еще не выполнена или успешно завершена.

...