【问题标题】:Upload a file to Firebase Storage and get a downloadUrl. How can I return the result in a Kotlin function?将文件上传到 Firebase 存储并获取 downloadUrl。如何在 Kotlin 函数中返回结果?
【发布时间】:2020-01-09 03:05:30
【问题描述】:

我有一个使用 uploadTask 将本地文件上传到 Firestore 存储的功能。我按照docs 中的说明进行操作。这是我的代码:

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 
}

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

【问题讨论】:

标签: android firebase kotlin firebase-storage


【解决方案1】:

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

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

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

【讨论】:

  • 在您的(强烈推荐!)帖子中提供了很好的解释和非常有用的答案和干净的解决方案。我今天学到了一些东西!
猜你喜欢
  • 2021-03-23
  • 2020-04-28
  • 1970-01-01
  • 2022-01-13
  • 2016-11-02
  • 1970-01-01
  • 2018-05-26
  • 2021-03-18
  • 2018-07-12
相关资源
最近更新 更多