RxJava: cómo devolver el tipo correcto de nulo
Estoy desarrollando una aplicación usando Firebase, Kotlin y RxJava.
Básicamente, lo que tengo que hacer es registrar a un usuario usando Auth de Firebase, si el usuario seleccionó una foto, suba la foto y luego guarde al usuario en la database de Firebase.
- RxJava Valor pnetworkingeterminado para throttleFirst
- ¿Por qué obtengo una android.os.TransactionTooLargeException en mi aplicación de Android escrita en Kotlin / rxJava cuando salgo de la aplicación? (onExit / onPause)?
- No se pudo deducir Kotlin y RxJava
- RxJava2 observable no procesando en Siguiente cuando hay un cambio
- Usando RxJava para get un resultado distinto con Realm y Retrofit
Hasta ahora tengo esto
RxFirebaseAuth.createUserWithEmailAndPassword(auth, email, password) .map { authResult -> user.uid = authResult.user.uid authResult.user.uid } .flatMap<UploadTask.TaskSnapshot>( { uid -> if (imageUri != null) RxFirebaseStorage.putFile(mFirebaseStorage .getReference(STORAGE_IMAGE_REFERENCE) .child(uid), imageUri) else Maybe.empty<UploadTask.TaskSnapshot>() } ) .map { taskSnapshot -> user.photoUrl = taskSnapshot.downloadUrl!!.toString() } .map { RxFirebaseDatabase .setValue(mFirebaseDatabase.getReference("user") .child(user.uid), user).subscribe() } .doOnComplete { appLocalDataStore.saveUser(user) } .toObservable()
Está funcionando correctamente cuando el usuario selecciona una foto, pero cuando no está seleccionada, los otros maps se ignoran, porque devolví Maybe.empty ().
¿Cómo debo implementar esto para trabajar con o sin una foto de usuario?
Gracias.
- Observable para reutilizar ejecuciones de operadores
- ¿Cómo se simula emitir 2 streams infinitas observables y tener otras observables que las fusionan y amortiguan cada 10 segundos?
- Cómo probar el observador?
- La biblioteca de Android no puede comstackr kotlin
- Operador RxJava para el método de conmutación
- OnComplete nunca se llamó con toSortedList () y groupBy ()
- Usando RxJava con Handler, restablece Message.what value
- Cómo escribir la testing adecuada para el repository de interfaz reactiva que devuelve Observable solo cuando hay algún evento, cómo simular el desencadenamiento de ese evento
Eche un vistazo a la siguiente construcción:
val temp = null Observable.just("some value") .flatMap { // Throw exception if temp is null if (temp != null) Observable.just(it) else Observable.error(Exception("")) } .onErrorReturnItem("") // return blank string if exception is thrown .flatMap { v -> Single.create<String>{ // do something it.onSuccess("Yepeee $v"); }.toObservable() } .subscribe({ System.out.println("Yes it worked: $it"); },{ System.out.println("Sorry: $it"); })
Debería lanzar un error si encuentra un nulo, y luego usar el onErrorReturn{}
o onErrorReturnItem()
para devolver un valor pnetworkingeterminado que se pasará a la siguiente cadena de operador sin saltar a onError
en Observer
.
Entonces su código debería verse así:
RxFirebaseAuth.createUserWithEmailAndPassword(auth, email, password) .map { authResult -> user.uid = authResult.user.uid authResult.user.uid } .flatMap<UploadTask.TaskSnapshot>( { uid -> if (imageUri != null) RxFirebaseStorage.putFile(mFirebaseStorage .getReference(STORAGE_IMAGE_REFERENCE) .child(uid), imageUri) else Observable.error<Exception>(Exception("null value")) // Throw exception if imageUri is null } ) .map { taskSnapshot -> user.photoUrl = taskSnapshot.downloadUrl!!.toString() } .onErrorReturn { user.photoUrl = "" // assign blank url string if exception is thrown } .map { RxFirebaseDatabase .setValue(mFirebaseDatabase.getReference("user") .child(user.uid), user).subscribe() } .doOnComplete { appLocalDataStore.saveUser(user) } .toObservable()
Pero hay un problema con este código de que se produjo una exception antes de que onErrorReturn
produzca un uri en blanco y dé como resultado una ejecución de cadena adicional que no queremos. Si se produce cualquier otra exception enError se debe invocar.
Para eso tenemos que crear una class Exception personalizada y atrapar esta exception lanzada en onErrorReturn
. Eche un vistazo al siguiente fragment:
... ... .flatMap<UploadTask.TaskSnapshot>( { uid -> if (imageUri != null) RxFirebaseStorage.putFile(mFirebaseStorage .getReference(STORAGE_IMAGE_REFERENCE) .child(uid), imageUri) else Observable.error<MyCustomException>(MyCustomException("null value")) // Throw exception if imageUri is null } ) .map { taskSnapshot -> user.photoUrl = taskSnapshot.downloadUrl!!.toString() } .onErrorReturn { if(it !is MyCustomException) throw it else user.photoUrl = "" // assign blank url string if exception is thrown } ... ...
Espero eso ayude.
- Implementación de readaptación en Kotlin – Parámetro por defecto del método
- ¿Cuál es la forma oficial / correcta de crear la entidad y el file Dao al usar kotlin?