[英]How to upload image to Firebase Storage and get the DownloadUrl Flutter
[英]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.