Log.d(TAG, "downloadImgsUriArrayList:$downloadImagesUriList ")
上载代码在迭代器的.addOnCompleteListener导致var downloadImagesUriList: MutableList<String> = mutableListOf()
为空之前执行。
如何解决此问题?
var downloadImagesUriList: MutableList<String> = mutableListOf()
//Upload images button
upload_imgs_button.setOnClickListener {
Log.d(TAG, "uploadImgsPath: $uploadImgsPath");
//Upload images to firebase storage
if (uploadImgsPath != null) {
for (uriForUpload in imagesList) {
val imgNameUUID = UUID.randomUUID().toString()
val withAppendedPath =
Uri.withAppendedPath(uriForUpload, imgNameUUID).toString()
var imgFileRef = uploadImgsPath!!.child(withAppendedPath)
imgFileRef.putFile(uriForUpload)
.continueWithTask {
if (!it.isSuccessful) {
it.exception?.let {
throw it
}
}
imgFileRef.downloadUrl
}.addOnCompleteListener {
if (it.isSuccessful) {
var uriForDownload = it.result.toString()
Log.d(TAG, "uriForDownload:$uriForDownload ");
downloadImagesUriList.add(uriForDownload)
}
}
}
//The process will run here before downloadImagesUriList.add(uriForDownload) was excuted.
//How to solve this problem?
Log.d(TAG, "downloadImgsUriArrayList:$downloadImagesUriList ");
var uploadedImages = UploadedImages(
categoryDesignID, user!!.uid,
downloadImagesUriList, Timestamp.now()
)
//Save uploaded images path info to firestore
firestore.collection("uploadedImages").add(uploadedImages)
.addOnSuccessListener {
Toast.makeText(context, "Upload successful", Toast.LENGTH_LONG)
.show()
}
} else {
Toast.makeText(context,"Please choose a category",Toast.LENGTH_LONG).show()
}
Firebase API,与大多数现代云API一样,是异步的,因为它们与(可能很耗时的)服务器交互。客户端允许您的主代码继续运行,而不是在云交互发生时阻塞您的主线程,然后在云API完成工作后再调用。
在您的代码中,这意味着Log.d(TAG, "downloadImgsUriArrayList:$downloadImagesUriList ");
运行之前 imgFileRef.downloadUrl
。这解释了为什么add(uploadedImages)
没有将任何内容写入数据库:尚未确定下载URL,因为仍在进行上载。
为了解决此问题,所有需要上载下载URL的代码都必须是该上载的完成侦听器[[inside。
最简单的方法是,每次文件上传完成时添加一个新URL:for (uriForUpload in imagesList) {
val imgNameUUID = UUID.randomUUID().toString()
val withAppendedPath =
Uri.withAppendedPath(uriForUpload, imgNameUUID).toString()
var imgFileRef = uploadImgsPath!!.child(withAppendedPath)
imgFileRef.putFile(uriForUpload)
.continueWithTask {
if (!it.isSuccessful) {
it.exception?.let {
throw it
}
}
imgFileRef.downloadUrl
}.addOnCompleteListener {
if (it.isSuccessful) {
var uriForDownload = it.result.toString()
Log.d(TAG, "uriForDownload:$uriForDownload ");
downloadImagesUriList.add(uriForDownload)
Log.d(TAG, "downloadImgsUriArrayList:$downloadImagesUriList ");
var uploadedImages = UploadedImages(
categoryDesignID, user!!.uid,
downloadImagesUriList, Timestamp.now()
)
//Save uploaded images path info to firestore
firestore.collection("uploadedImages").add(uploadedImages)
}
}
}
以上将在每次上传完成时创建一个新文档。每个文件完成后,您将任一想要更新同一文档。或等到最后一个文件上传之后,再创建文档。可以通过多种方法进行操作,但是一种简单的方法是简单地对完成上传的文件数进行计数:
var uploadedCount = 0 for (uriForUpload in imagesList) { ... }.addOnCompleteListener { if (it.isSuccessful) { var uriForDownload = it.result.toString() Log.d(TAG, "uriForDownload:$uriForDownload "); downloadImagesUriList.add(uriForDownload) if (uploadedCount++ >= imagesList.size) { Log.d(TAG, "downloadImgsUriArrayList:$downloadImagesUriList "); var uploadedImages = UploadedImages( categoryDesignID, user!!.uid, downloadImagesUriList, Timestamp.now() ) //Save uploaded images path info to firestore firestore.collection("uploadedImages").add(uploadedImages) } ... }