【问题标题】:RxJava: how to return the correct type of nullRxJava:如何返回正确的 null 类型
【发布时间】:2018-01-29 00:54:48
【问题描述】:

我正在使用 Firebase、Kotlin 和 RxJava 开发应用程序。

基本上,我需要做的是使用 Firebase 的 Auth 注册用户,如果用户选择了一张照片,则上传照片,然后将用户从 Firebase 保存到数据库中。

直到现在我都有这个

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()

当用户选择一张照片时它工作正常,但当它没有被选择时,其他地图被忽略,因为我返回了 Maybe.empty()。

我应该如何实现它以使用或不使用用户照片?

谢谢。

【问题讨论】:

    标签: android firebase firebase-authentication kotlin rx-java


    【解决方案1】:

    看看下面的构造:

            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");
                    })
    

    如果遇到空值,应该抛出错误,然后使用onErrorReturn{}onErrorReturnItem() 运算符返回一个默认值,该值将传递给下一个运算符链,而不会跳转到Observer 中的onError

    所以你的代码应该是这样的:

    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()
    

    但是这段代码有一个问题,在onErrorReturn 之前发生的任何异常都会产生一个空白 uri 并导致我们不希望的进一步链执行。如果发生任何其他异常,则应调用 onError。

    为此,我们需要创建一个自定义异常类并在onErrorReturn 中捕获这个抛出的异常。看看下面的sn-p:

    ...
    ...
    
    .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
    
                    }
    ...
    ...
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      相关资源
      最近更新 更多