Я создаю приложение для ресторана, и при создании нового ресторана мне нужно, чтобы все фотографии меню и ресторана были загружены в хранилище.Я просматриваю список всех путей к файлам для загрузки каждой фотографии.
Затем для каждой фотографии, которую я хочу получить взамен URL, где она хранится, добавьте ее в список в моем объекте Restaurant,и только затем записать этот объект в базу данных (Cloud Firestore).
Я сохраняю список путей к файлам в newRestaurant.menu_photos
и newRestaurant.restaurant_photos
, а когда загрузка завершится, я просто хочу заменить эти списки насписки загруженных URL-адресов.
Я пытаюсь понять, как работают сопрограммы, но немного теряется.Независимо от того, что я пытаюсь, объект Restaurant записывается, не дожидаясь окончания загрузки изображения.
Это мой код на данный момент:
next.setOnClickListener {
val newRestaurantDoc = db.collection("restaurants").document()
CoroutineScope(IO).launch {
for (menuImage in newRestaurant.menu_photos) {
uploadPhoto(
Uri.fromFile(File(menuImage)),
newRestaurantDoc.id,
"menu",
0
)
}
}
CoroutineScope(IO).launch {
for (restaurantImage in newRestaurant.restaurant_photos) {
uploadPhoto(
Uri.fromFile(File(restaurantImage)),
newRestaurantDoc.id,
"restaurant",
1
)
}
}
newRestaurant.menu_photos = finalListMenuImages
newRestaurant.restaurant_photos = finalListRestaurantImages
newRestaurant.id = newRestaurantDoc.id
newRestaurantDoc.set(newRestaurant).addOnSuccessListener {
//go to home
Toast.makeText(activity, "Successfully created new restaurant", Toast.LENGTH_SHORT)
.show()
}
}
Затем функция загрузки:
private suspend fun uploadPhoto(
photoUri: Uri,
restID: String,
section: String,
case: Int
) {
val refImage =
FirebaseStorage.getInstance().getReference("/images/$restID/$section/$randomName")
val path =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString() + File.separator + "getit"
val imageFile: File = File.createTempFile("ImageFile", "temporary")
val myInputStream =
(activity as MainActivity).contentResolver.openInputStream(Uri.parse(photoUri.toString()))
FileUtils.copyInputStreamToFile(myInputStream, imageFile)
changeListOnMain(
refImage.putFile(
Uri.fromFile(
Resizer(this.context)
.setTargetLength(1200)
.setQuality(100)
.setOutputFormat("PNG")
.setOutputFilename(randomName)
.setOutputDirPath(path)
.setSourceImage(imageFile)
.resizedFile
)
)
.await() // await() instead of snapshot
.storage
.downloadUrl
.result!!, case
)
}
И затем я пытаюсь завершить работу в главном потоке:
private suspend fun changeListOnMain(uploadedImageUri: Uri, case: Int) {
withContext(Main) {
if (case == 0) {
finalListMenuImages.add(uploadedImageUri.toString())
} else {
finalListRestaurantImages.add(uploadedImageUri.toString())
}
val fileBig = File(uploadedImageUri.path)
if (fileBig.exists()) {
fileBig.delete()
}
}
}
Но, как я уже сказал, как только я нажимаю кнопку next
, он просто пишет объект.