如何在所有forEach执行完成后读取Firebase存储URL列表?
解决Firebase Storage批量上传后等待所有下载URL获取完成的问题
你的问题核心在于:获取下载URL的downloadUrl.addOnSuccessListener是异步操作,forEach只是循环触发这些异步任务,但不会等待它们全部执行完毕,所以你在循环外打印列表时,所有异步任务还没完成,自然是空的。
正确实现代码
把每个获取下载URL的操作都包装成Task,再用Tasks.whenAllSuccess等待所有URL任务完成后,再统一处理结果:
Tasks.whenAllSuccess<UploadTask>(tasks).addOnSuccessListener { val urlTasks = mutableListOf<Task<Uri>>() tasks.forEach { uploadTask -> val urlTask = uploadTask.result.metadata!!.reference!!.downloadUrl urlTasks.add(urlTask) } // 等待所有获取URL的异步任务完成 Tasks.whenAllSuccess<Uri>(urlTasks).addOnSuccessListener { uris -> val downloadUrls = uris.map { it.toString() }.toMutableList() // 此时URL列表已完全填充,可以安全使用 Log.d("List with URLs", downloadUrls.toString()) progressDialog.dismiss() // 按需打印单个URL downloadUrls.forEach { url -> Log.e("Downloadable Image URL", url) } } }
关键逻辑说明
- 第一层
Tasks.whenAllSuccess确保所有上传任务完成,这一步你原本的实现是对的。 - 为每个上传完成的任务,创建获取下载URL的
Task<Uri>并收集到列表中,避免直接在循环内嵌套异步监听。 - 第二层
Tasks.whenAllSuccess等待所有URL获取任务结束,此时返回的uris就是所有下载URL的完整集合,直接转换为字符串列表即可使用。
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

