将文件上传到 Firebase Storage 并获取 downloadUrl。如何在 Kotlin 函数中返回结果?

CEO*_*pps 5 android kotlin firebase firebase-storage

我有一个功能,可以使用uploadTask. 我按照文档中给出的说明进行操作。这是我的代码:

fun uploadAudioFile(file: File){
    val audioFilePathUri = Uri.fromFile(file)
    val ref = currentUserRef.child("audioFiles/" + System.currentTimeMillis() + "." + "m4a")
    val uploadTask = ref.putFile(audioFilePathUri)

    val urlTask =
        uploadTask.continueWithTask(Continuation<UploadTask.TaskSnapshot, Task<Uri>> { task ->
            if (!task.isSuccessful) {
                task.exception?.let {
                    throw it
                }
            }
            return@Continuation ref.downloadUrl
        }).addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val downloadUri = task.result
                Log.d("STORAGE_UTIL", "downloadUri: " + downloadUri)
            } else {
                // Handle failures
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

该函数工作正常并呈现正确的downloadUri

现在我的问题:我想重写这个函数,以便它返回downloadUri。像这样的东西:

 fun uploadAudioFile(file: File): Uri? {
    val audioFilePathUri = Uri.fromFile(file)
    val ref = currentUserRef.child("audioFiles/" + System.currentTimeMillis() + "." + "m4a")
    val uploadTask = ref.putFile(audioFilePathUri)

    val urlTask =
        uploadTask.continueWithTask(Continuation<UploadTask.TaskSnapshot, Task<Uri>> { task ->
            if (!task.isSuccessful) {
                task.exception?.let {
                    throw it
                }
            }
            return@Continuation ref.downloadUrl
        }).addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val downloadUri = task.result
                Log.d("STORAGE_UTIL", "downloadUri: " + downloadUri)
            } else {
                // Handle failures
            }
        }
    return downloadUri 
}
Run Code Online (Sandbox Code Playgroud)

这为我提供了有关 return 语句的downloadUri的未解析引用。我该如何解决这个问题?

Ale*_*amo 5

您无法返回downloadUri方法结果,这是因为 Firebase API 是asynchronous. 这意味着onComplete()函数在调用后立即返回,并且Task它返回的回调将在一段时间后被调用。因此,不幸的是,无法保证需要多长时间,可能需要几百毫秒到几秒的时间才能获得数据。由于该方法立即返回,因此您尝试返回的变量值downloadUri尚未从回调中填充。

基本上,您尝试从异步 API 同步返回值。这不是一个好主意。您应该按预期异步处理 API。

解决此问题的一个快速方法是在方法内部使用downloadUri变量的值。基本上,方法中存在的所有逻辑都应该移动到回调中。如果您想在回调之外使用该值,我建议您查看这篇文章中我的答案的最后部分,其中我解释了如何使用自定义回调来完成此操作。onComplete()uploadAudioFile()


归档时间:

查看次数:

1062 次

最近记录:

5 年,7 月 前