Загрузить список файлов в Firebase и вернуть Single - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть функция, которая загружает список аудиофайлов в базу данных Firebase Realtime.Каждая успешная загрузка файла возвращает downloadUrl, и я сохранял это в list до тех пор, пока рекурсия не прекратится.Можно ли обернуть эту функцию вокруг RxJava, чтобы вернуть Single<List<String>>?

fun uploadAudioList(list: MutableList<Audio>, userId: String){

    val audio = list[index]

    //userid/audio/filename
    val fileRef = storageReference.child(String.format(FirebaseUtil.ADD_FIREBASE_AUDIO,
            userId, "audio", audio.filename))

    val metadata = StorageMetadata.Builder()
            .setContentType(audio.mimeType).build()

    fileRef.putFile(audio.uri, metadata)
            .continueWithTask { task: Task<UploadTask.TaskSnapshot> ->
                if (!task.isSuccessful) {
                    Log.e(TAG, "Audio upload task error ${task.exception!!}")
                }
                return@continueWithTask fileRef.downloadUrl
            }.addOnCompleteListener { uri ->
                urlList.add(uri.result.toString()) //Return this as Single<List<String>>
                if (index < list.lastIndex) {
                    index++
                    uploadAudioList(list, userId) //Recursive until all Audio are uploaded
                }
            }.addOnFailureListener {
                Log.e(TAG, "Uploading audio failed ${it.message}")
            }
}

1 Ответ

0 голосов
/ 13 февраля 2019

Редизайн вашей функции выглядит следующим образом:

fun uploadAudioList(list: MutableList<Audio>, userId: String): Single<List<String>> =
    Observable.create<String> { emitter ->

        // Call emitter.onNext(url) for each individual upload

        // Call emitter.onComplete() after all elements have been emitted

        // Call emitter.onError(exception) if you want to propagate any exceptions that occur


    }.toList() // This function takes every element emitted by Observable<String>, waits for 
               // onComplete() to be called, and then puts them into a Single<List<String>>

Теперь, когда вы хотите вызвать свою функцию, используйте subscribe или blockingGet на uploadAudioList, например:

val urlList = uploadAudioList(...)
    .subscribeOn(Schedulers.io()) // This specifies that the function should run in the background
    .observeOn(AndroidSchedulers.mainThread()) // This specifies that the result should be available
                                               // on this thread (presumably you want the main thread)
    .blockingGet() // This is a blocking call that waits for the task to finish and return the result
                   // Use subscribe(...) for more advanced asynchronous use cases
...