Как работают обратные вызовы завершения Firebase в Котлине - PullRequest
0 голосов
/ 26 июня 2018

Я успешно прочитал данные из Firebase и отобразил их в imageView асинхронно, используя обратный вызов завершения. Будучи новичком в программировании, мне все еще трудно понять некоторые механизмы, связанные с обратными вызовами, и надеюсь, что кто-то будет любезен, чтобы пролить свет на некоторые из моих вопросов. Я уже прочитал и посмотрел несколько учебных пособий и объяснений, но все еще не могу понять некоторые концепции. Вот мой Firebase код:

Часть 1:

readFirebaseData(object: FirebaseCallback{
        override fun onCallback(list: MutableList<RecipeTemplate>) {

            glideVariable?.loadImageUrl(recipeArray[1].recipeImage) //WORKS!!
        }
})

Часть 2:

fun readFirebaseData(firebaseCallback: FirebaseCallback) {
    ref!!.addValueEventListener(object: ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot?) {

            for (item in snapshot!!.children) {
                var tempRecipe = RecipeTemplate()
                val image = item.child("recipeImageFirebase")

                tempRecipe.recipeImage = image.value.toString()
                recipeArray.add(tempRecipe)
            }
            //INSERTING CODE HERE AT LATER STAGE... SEE LATER IN POST
            firebaseCallback.onCallback(recipeArray)

        }//END ON DATA CHANGE METHOD
    }) //END FB
}//END READ DATA

Часть 3:

interface FirebaseCallback {
    fun onCallback(list: MutableList<RecipeTemplate>)
}

Главное, что я не понимаю смысла интерфейса и всей функции переопределения (ЧАСТЬ 1). Дело в том, что я успешно проделал то же самое, просто используя вызов функции в конце кода Firebase. Он требует гораздо меньше кода, его легче понять и понять, и, насколько я могу судить, он делает то же самое. Это выглядит так:

Внутри ЧАСТИ 2:

test(recipeArray) //SIMPLY CALLING A FUNCTION INSTEAD OF THE CODE PREVIOUSLY USED.
//firebaseCallback.onCallback(recipeArray)

Тогда сама функция проверки:

 fun test(list: MutableList<RecipeTemplate>) {
    Log.d("TAGM", "DONE WITH FB")
    glideVariable?.loadImageUrl(recipeArray[3].recipeImage)    
}

Итак, что мне здесь не хватает? Зачем использовать весь интерфейс обратного вызова?

1 Ответ

0 голосов
/ 26 июня 2018

Чтобы решить эту проблему, вам нужно создать свой собственный обратный вызов, чтобы дождаться, пока Firebase вернет вам данные. Для этого сначала нужно создать interface, например:

interface FirebaseCallback {
    fun onCallback(list: MutableList<RecipeTemplate>)
}

Затем вам нужно создать функцию, которая фактически получает данные из базы данных. Эта функция должна выглядеть так:

fun readFirebaseData(firebaseCallback: FirebaseCallback) {
    ref.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            val list = ArrayList<RecipeTemplate>()
            for (ds in dataSnapshot.getChildren()) {
                val recipeTemplate = ds.getValue(RecipeTemplate::class.java!!)
                list.add(recipeTemplate)
            }
            firebaseCallback.onCallback(list)
        }

        override fun onCancelled(databaseError: DatabaseError) {}
    })
}

В конце просто вызовите функцию readData() и передайте экземпляр интерфейса FirebaseCallback в качестве аргумента, где бы он вам ни понадобился, например:

readFirebaseData(object : FirebaseCallback {
    override fun onCallback(list: MutableList<RecipeTemplate>) {
        //Do what you need to do with your list
    }
})

Это единственный способ использовать это значение вне функции onDataChange().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...