I'm using Firebase to upload an image. I'm using Firebase's .onCompleteListener()
to get the URL of the uploaded image in the callback.
I'm trying to incoorporate this into my Repository
class with a Single<>
, but I'm unsure how to do it.
Could someone please help me figure out what I'm doing incorrectly?
public Single<String> uploadImage(String path) {
Uri uri = Uri.fromFile(new File(path));
String fileName = createNewFileName(uri);
StorageReference ref = firebaseStorage.getReference().child(fileName);
return Single.fromCallable(() -> {
UploadTask uploadTask = ref.putFile(uri);
uploadTask.continueWithTask(task -> {
if (!task.isSuccessful()) {
throw task.getException();
}
return ref.getDownloadUrl();
}).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
String url = downloadUri.toString();
//String to use in Single<>
} else {
//Handle Error
}
});
});
}
To use in my ViewModel
uploadImage(path)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(url -> {
}, err -> {
});
You need Single.create
:
Provides an API (via a cold Single) that bridges the reactive world with the callback-style world.
return Single.<String>create(emitter -> {
UploadTask uploadTask = ref.putFile(uri);
uploadTask.continueWithTask(task -> {
if (!task.isSuccessful()) {
throw task.getException();
}
return ref.getDownloadUrl();
}).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
String url = downloadUri.toString();
emitter.onSuccess(url);
} else {
emitter.onError(task.getException());
}
});
});