繁体   English   中英

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

[英]Upload a file to Firebase Storage and get a downloadUrl. How can I return the result in a Kotlin function?

我有一个使用uploadTask将本地文件上传到 Firestore 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
            }
        }
}

该函数工作正常并呈现正确的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 
}

这给了我一个未解析的关于 return 语句的downloadUri 的参考 我该如何解决这个问题?

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

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

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

这是因为您在监听器中声明了它,而return语句无法访问它。

这样返回

if (task.isSuccessful) {
                val downloadUri = task.result
                Log.d("STORAGE_UTIL", "downloadUri: " + downloadUri)
                return downloadUri
            } else {
                // Handle failures
            }

当使用类似UploadTask的异步调用时,请务必确保在异步调用完成后运行依赖于异步调用响应的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM