我正在使用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()
当用户选择照片时,它可以正常工作,但是当未选择照片时,其他 map 将被忽略,因为我返回了Maybe.empty()。
无论有没有用户照片,我应该如何实现?
谢谢。
最佳答案
看一下下面的构造:
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");
})
如果遇到null,则应该抛出错误,然后使用
onErrorReturn{}
或onErrorReturnItem()
运算符返回默认值,该默认值将传递到下一个运算符链,而无需跳转到onError
中的Observer
。因此,您的代码应如下所示:
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。为此,我们需要创建一个自定义Exception类,并在
onErrorReturn
中捕获此引发的异常。看看以下片段:...
...
.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
}
...
...
希望能帮助到你。