来自 Firebase 实时数据库的数据被检索,但从函数返回时未设置?
Data from Firebase Realtime Database is retreived, but not set when returned from a function?
我正在尝试从 Firebase 获取数据并将其作为数组 return。到目前为止这是有效的,但是数据仍然是我设置的默认数据。
这是代码(我添加了一些注释来阐明它在哪里工作以及 id 不工作的地方):
fun getRandomQuestion() : ArrayList<ArrayList<String>>{
val random = Random(1234567)
val randQuestionId = random.nextInt(0, 27)
var dataRequestResult : String = "empty"
var requestSide1 : String = "empty"
var requestSide2 : String = "empty"
var requestCount1 : String = "empty"
var requestCount2 : String = "empty"
//Get a random question from the DB
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
Log.i("Get WYR Question Status", "Failed: " + task.message.toString())
requestSide1 = "empty"
requestSide2 = "empty"
requestCount1 = "empty"
requestCount2 = "empty"
}.addOnSuccessListener {
Log.i("Get WYR Question Status", "Success")
//Logging this data returns the correct information from firebase, no issue here
Log.i("Request Data Result", it.value.toString())
dataRequestResult = it.value.toString()
}
requestSide1 = dataRequestResult.substringAfter("side1Question=").substringBefore("}")
requestSide2 = dataRequestResult.substringAfter("side2Question=").substringBefore(",")
requestCount1 = dataRequestResult.substringAfter("sideCount1=").substringBefore(",")
requestCount2 = dataRequestResult.substringAfter("sideCount2=").substringBefore(",")
//Return the value
return arrayListOf(arrayListOf(requestSide1, requestCount1), arrayListOf(requestSide2, requestCount2))
}
Activity 我尝试获取 returned 值:
val myQuestion = databaseController.getRandomQuestion()
//This is where the issue lies
//When I get the returned data from the function above, it gives me all of the defaults I had set in the function (which is "empty")
//It logs:`[["empty", "empty"],["empty", "empty"]]`
Log.i("My Question", myQuestion.toString())
成功监听器中的数据是正确的,但return值仍然是默认值。
这是日志的图像:
“请求日志结果”,不要介意结果,我正在做一个WYR应用程序。
我注意到监听器的请求是最后一个,而不是第一个
我认为这与数据尚未完全收集有关,因为在我制作的另一个应用程序中,我所要做的就是给它一个延迟,它会被设置,但在这种情况下,我有不知道该怎么办。
如有任何帮助,我们将不胜感激! :)
这是我的解决方案
方法一
fun getRandomQuestion() : ArrayList<ArrayList<String>>{
val random = Random(1234567)
val randQuestionId = random.nextInt(0, 27)
var dataRequestResult : String = "empty"
var requestSide1 : String = "empty"
var requestSide2 : String = "empty"
var requestCount1 : String = "empty"
var requestCount2 : String = "empty"
//Get a random question from the DB
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
Log.i("Get WYR Question Status", "Failed: " + task.message.toString())
requestSide1 = "empty"
requestSide2 = "empty"
requestCount1 = "empty"
requestCount2 = "empty"
}.addOnSuccessListener {
Log.i("Get WYR Question Status", "Success")
//Logging this data returns the correct information from firebase, no issue here
Log.i("Request Data Result", it.value.toString())
dataRequestResult = it.value.toString()
requestSide1 = dataRequestResult.substringAfter("side1Question=").substringBefore("}")
requestSide2 = dataRequestResult.substringAfter("side2Question=").substringBefore(",")
requestCount1 = dataRequestResult.substringAfter("sideCount1=").substringBefore(",")
requestCount2 = dataRequestResult.substringAfter("sideCount2=").substringBefore(",")
}
//Return the value
return arrayListOf(arrayListOf(requestSide1, requestCount1), arrayListOf(requestSide2, requestCount2))
}
方法二
fun getRandomQuestion() : ArrayList<ArrayList<String>>{
val random = Random(1234567)
val randQuestionId = random.nextInt(0, 27)
var dataRequestResult : String = "empty"
var requestSide1 : String = "empty"
var requestSide2 : String = "empty"
var requestCount1 : String = "empty"
var requestCount2 : String = "empty"
//Get a random question from the DB
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
Log.i("Get WYR Question Status", "Failed: " + task.message.toString())
requestSide1 = "empty"
requestSide2 = "empty"
requestCount1 = "empty"
requestCount2 = "empty"
}.addOnSuccessListener {
Log.i("Get WYR Question Status", "Success")
//Logging this data returns the correct information from firebase, no issue here
Log.i("Request Data Result", it.value.toString())
dataRequestResult = it.value.toString()
requestSide1 = dataRequestResult.substringAfter("side1Question=").substringBefore("}")
requestSide2 = dataRequestResult.substringAfter("side2Question=").substringBefore(",")
requestCount1 = dataRequestResult.substringAfter("sideCount1=").substringBefore(",")
requestCount2 = dataRequestResult.substringAfter("sideCount2=").substringBefore(",")
//Return the value
return arrayListOf(arrayListOf(requestSide1, requestCount1), arrayListOf(requestSide2, requestCount2))
}
return null
}
您在请求数据库数据时使用的侦听器将比 getRandomQuestion
函数 returns ArrayList
更晚触发。您可以使用 Kotlin coroutines 来处理回调并挂起协程直到触发回调,例如:
suspend fun getRandomQuestion() = suspendCoroutine<String> { continuation ->
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
continuation.resume("empty")
}.addOnSuccessListener {
continuation.resume(it.value.toString())
}
}
// somewhere in your code (e.g. in ViewModel, Activity or Fragment):
someCoroutineScope.launch {
val question: String = getRandomQuestion();
// ... use question to update UI
}
在Activity
或Fragment
中你可以使用lifecycleScope
, in ViewModel
- viewModelScope
.
suspendCoroutine
构建器函数用于等待回调。 suspendCoroutine
暂停执行它的协程,直到我们决定通过调用适当的方法继续 - Continuation.resume...
.
我正在尝试从 Firebase 获取数据并将其作为数组 return。到目前为止这是有效的,但是数据仍然是我设置的默认数据。
这是代码(我添加了一些注释来阐明它在哪里工作以及 id 不工作的地方):
fun getRandomQuestion() : ArrayList<ArrayList<String>>{
val random = Random(1234567)
val randQuestionId = random.nextInt(0, 27)
var dataRequestResult : String = "empty"
var requestSide1 : String = "empty"
var requestSide2 : String = "empty"
var requestCount1 : String = "empty"
var requestCount2 : String = "empty"
//Get a random question from the DB
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
Log.i("Get WYR Question Status", "Failed: " + task.message.toString())
requestSide1 = "empty"
requestSide2 = "empty"
requestCount1 = "empty"
requestCount2 = "empty"
}.addOnSuccessListener {
Log.i("Get WYR Question Status", "Success")
//Logging this data returns the correct information from firebase, no issue here
Log.i("Request Data Result", it.value.toString())
dataRequestResult = it.value.toString()
}
requestSide1 = dataRequestResult.substringAfter("side1Question=").substringBefore("}")
requestSide2 = dataRequestResult.substringAfter("side2Question=").substringBefore(",")
requestCount1 = dataRequestResult.substringAfter("sideCount1=").substringBefore(",")
requestCount2 = dataRequestResult.substringAfter("sideCount2=").substringBefore(",")
//Return the value
return arrayListOf(arrayListOf(requestSide1, requestCount1), arrayListOf(requestSide2, requestCount2))
}
Activity 我尝试获取 returned 值:
val myQuestion = databaseController.getRandomQuestion()
//This is where the issue lies
//When I get the returned data from the function above, it gives me all of the defaults I had set in the function (which is "empty")
//It logs:`[["empty", "empty"],["empty", "empty"]]`
Log.i("My Question", myQuestion.toString())
成功监听器中的数据是正确的,但return值仍然是默认值。 这是日志的图像:
“请求日志结果”,不要介意结果,我正在做一个WYR应用程序。
我注意到监听器的请求是最后一个,而不是第一个
我认为这与数据尚未完全收集有关,因为在我制作的另一个应用程序中,我所要做的就是给它一个延迟,它会被设置,但在这种情况下,我有不知道该怎么办。
如有任何帮助,我们将不胜感激! :)
这是我的解决方案
方法一
fun getRandomQuestion() : ArrayList<ArrayList<String>>{
val random = Random(1234567)
val randQuestionId = random.nextInt(0, 27)
var dataRequestResult : String = "empty"
var requestSide1 : String = "empty"
var requestSide2 : String = "empty"
var requestCount1 : String = "empty"
var requestCount2 : String = "empty"
//Get a random question from the DB
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
Log.i("Get WYR Question Status", "Failed: " + task.message.toString())
requestSide1 = "empty"
requestSide2 = "empty"
requestCount1 = "empty"
requestCount2 = "empty"
}.addOnSuccessListener {
Log.i("Get WYR Question Status", "Success")
//Logging this data returns the correct information from firebase, no issue here
Log.i("Request Data Result", it.value.toString())
dataRequestResult = it.value.toString()
requestSide1 = dataRequestResult.substringAfter("side1Question=").substringBefore("}")
requestSide2 = dataRequestResult.substringAfter("side2Question=").substringBefore(",")
requestCount1 = dataRequestResult.substringAfter("sideCount1=").substringBefore(",")
requestCount2 = dataRequestResult.substringAfter("sideCount2=").substringBefore(",")
}
//Return the value
return arrayListOf(arrayListOf(requestSide1, requestCount1), arrayListOf(requestSide2, requestCount2))
}
方法二
fun getRandomQuestion() : ArrayList<ArrayList<String>>{
val random = Random(1234567)
val randQuestionId = random.nextInt(0, 27)
var dataRequestResult : String = "empty"
var requestSide1 : String = "empty"
var requestSide2 : String = "empty"
var requestCount1 : String = "empty"
var requestCount2 : String = "empty"
//Get a random question from the DB
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
Log.i("Get WYR Question Status", "Failed: " + task.message.toString())
requestSide1 = "empty"
requestSide2 = "empty"
requestCount1 = "empty"
requestCount2 = "empty"
}.addOnSuccessListener {
Log.i("Get WYR Question Status", "Success")
//Logging this data returns the correct information from firebase, no issue here
Log.i("Request Data Result", it.value.toString())
dataRequestResult = it.value.toString()
requestSide1 = dataRequestResult.substringAfter("side1Question=").substringBefore("}")
requestSide2 = dataRequestResult.substringAfter("side2Question=").substringBefore(",")
requestCount1 = dataRequestResult.substringAfter("sideCount1=").substringBefore(",")
requestCount2 = dataRequestResult.substringAfter("sideCount2=").substringBefore(",")
//Return the value
return arrayListOf(arrayListOf(requestSide1, requestCount1), arrayListOf(requestSide2, requestCount2))
}
return null
}
您在请求数据库数据时使用的侦听器将比 getRandomQuestion
函数 returns ArrayList
更晚触发。您可以使用 Kotlin coroutines 来处理回调并挂起协程直到触发回调,例如:
suspend fun getRandomQuestion() = suspendCoroutine<String> { continuation ->
Firebase.database.reference.child(Constants.wyrDBQuestionLocation)
.child(randQuestionId.toString())
.get()
.addOnFailureListener { task ->
continuation.resume("empty")
}.addOnSuccessListener {
continuation.resume(it.value.toString())
}
}
// somewhere in your code (e.g. in ViewModel, Activity or Fragment):
someCoroutineScope.launch {
val question: String = getRandomQuestion();
// ... use question to update UI
}
在Activity
或Fragment
中你可以使用lifecycleScope
, in ViewModel
- viewModelScope
.
suspendCoroutine
构建器函数用于等待回调。 suspendCoroutine
暂停执行它的协程,直到我们决定通过调用适当的方法继续 - Continuation.resume...
.