在Log.d(TAG,“ downloadImgsUriArrayList:$ downloadImagesUriList”)之后,迭代器的.addOnCompleteListener上载代码已执行

问题描述 投票:0回答:1

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()
    }
android kotlin firebase-storage
1个回答
0
投票

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) } ... }
© www.soinside.com 2019 - 2024. All rights reserved.