Issue
I am working on a project and I need to upload images to Firebase storage and get the download url before I can upload the associated model class to Firestore.
I am trying to use countdown latches to block the main thread until the upload is complete. I know there are better methods out there and feel free to recommend some but I figured I could just through up a brief load screen. The issue is that the callback for the getDownloadurl task never gets called. I have searched and searched and can't figure it out. Right now my code is straight from the documentation.
fun uploadListing(listing: Listing, images: ArrayList<ByteArray>, onCompleteListener: () -> Unit = {}) {
val listingRef = FirebaseFirestore.getInstance().collection(LISTINGS_COLLECTION).document()
val storageRef = FirebaseStorage.getInstance().reference
listing.id = listingRef.id
val countDownLatch = CountDownLatch(images.size)
var i = 0
images.forEach {
val imageRef = storageRef.child("images/${listing.id}/$i")
val uploadTask = imageRef.putBytes(it)
uploadTask.continueWithTask(Continuation<UploadTask.TaskSnapshot, Task<Uri>> { task ->
if (!task.isSuccessful) {
task.exception?.let { exception ->
throw exception
}
}
return@Continuation imageRef.downloadUrl
}).addOnCompleteListener { task ->
if (task.isSuccessful) {
listing.images.add(task.result.toString())
countDownLatch.countDown()
} else {
// Handle failures
// ...
}
}
}
countDownLatch.await()
listingRef.set(listing).addOnSuccessListener {
onCompleteListener()
}
}
My gradle dependencies...
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.google.firebase:firebase-firestore:17.1.5'
implementation 'com.google.firebase:firebase-storage:16.0.5'
implementation 'com.google.firebase:firebase-auth:16.1.0'
implementation 'com.google.firebase:firebase-core:16.0.6'
implementation 'com.squareup.picasso:picasso:2.5.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.5.3'
implementation 'com.google.code.gson:gson:2.8.5'
}
Solution
Don't ever block the main thread. This is usually a terrible idea (as you have just discovered) and could cause your app to crash with an ANR.
If you want to register another callback when a bunch of tasks are complete, use one of the variants of Tasks.whenAll() and pass it all the tasks you want to complete before moving to the next item of work.
Answered By - Doug Stevenson
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.