为何Firebase Storage操作中赋值的link变量仍会变为null?
Firebase Storage获取下载链接后外部变量为null的解决方案
问题原因
Firebase Storage的putFile()和downloadUrl都是异步操作,它们的回调代码会在后台任务完成后才执行。而你在shareOperation函数中回调外部的代码会先于回调执行,此时link还没被赋值,自然是null。
解决方案
方案1:将分享逻辑放在回调内部
直接在获取到下载链接的成功回调里执行分享Intent,确保链接已被正确赋值:
private fun shareOperation(file: File) { val uri = Uri.fromFile(file) val storage = FirebaseStorage.getInstance() val pdfRef = storage.reference.child("pdf/${uri.lastPathSegment}") pdfRef.putFile(uri) .addOnFailureListener { e -> Log.e(TAG, "Couldn't share " + e.message) } .addOnSuccessListener { // 上传成功后获取下载链接 pdfRef.downloadUrl.addOnSuccessListener { downloadUri -> val link = downloadUri.toString() Log.i(TAG, link) // 立即执行分享逻辑 launchShareIntent(link) } } } private fun launchShareIntent(link: String) { val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, link) } startActivity(Intent.createChooser(shareIntent, "分享文件链接")) }
方案2:用Kotlin协程简化异步逻辑
借助协程将异步代码转为同步写法,避免回调嵌套,代码更易读:
首先确保添加协程依赖(如果未添加):
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3"
然后修改代码:
// 在Activity/Fragment中使用lifecycleScope,ViewModel中用viewModelScope private fun shareOperation(file: File) = lifecycleScope.launch { val uri = Uri.fromFile(file) val storage = FirebaseStorage.getInstance() val pdfRef = storage.reference.child("pdf/${uri.lastPathSegment}") try { // 等待文件上传完成 pdfRef.putFile(uri).await() // 等待获取下载链接 val downloadUri = pdfRef.downloadUrl.await() val link = downloadUri.toString() Log.i(TAG, link) // 执行分享 launchShareIntent(link) } catch (e: Exception) { Log.e(TAG, "Couldn't share " + e.message) } } private fun launchShareIntent(link: String) { val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, link) } startActivity(Intent.createChooser(shareIntent, "分享文件链接")) }
内容的提问来源于stack exchange,提问作者yash nayak
相关产品推荐
相关产品推荐

