I have an application where I am using Firebase and RxSwift. I am getting snapshot from a ref and the issue I have now is the ref could be null i.e it does not exist. how do I still make my code run to by pass the null reason
if Null, I should call onCompleted.
func refreshActiveTrip() -> Observable<Trip> {
guard let trip = getCurrentTrip() else {
return Observable.error(RxError.noElements)
}
tripRef = Database.database().reference(forTransportChampionId: (getChampion()?.id)!, tripId: trip.id!)
return Observable<Trip>.create({ (observer) -> Disposable in
let disposable = Disposables.create {
self.tripRef?.removeAllObservers()
}
self.tripRef?.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists(){
if let data = snapshot.value as? [String: AnyObject] {
let trip = Trip(dictionary: data as NSDictionary)
print("SPLASH TRIP CURRENT \(data)")
self.saveCurrentTrip(trip)
observer.onNext(trip)
observer.onCompleted()
}
print("It exists!!")
}else{
let trip = Trip()
self.saveCurrentTrip(trip)
print("Nope, doesn't exist!")
}
})
return disposable
})
}
the tripRef
could be null
Since you are already creating an Observable with Observable.create()
, you can simply call observer.onCompleted()
in your else clause.
That said, it seems to me that you should be emitting the Trip()
object that you created instead and then saving it outside this function.
More information:
For what you are doing, would expect something more like this:
func refreshActiveTrip(_ trip: Trip?, championId: String) -> Observable<Trip> {
guard let trip = trip else { return Observable.error(RxError.noElements) }
return Observable.create { observer in
let tripRef = Database.database().reference(forTransportChampionId: championId, tripId: trip.id!)
tripRef.observeSingleEvent(of: .value, with: { snapshot in
var trip = Trip()
if snapshot.exists(), let data = snapshot.value as? [String: AnyObject] {
trip = Trip(dictionary: data as NSDictionary)
}
observer.onNext(trip)
observer.onCompleted()
})
return Disposables.create { tripRef.removeAllObservers() }
}
}
Note that the above is a free function; it is not inside any class.
To fully realize the code you have, it would be used like this:
refreshActiveTrip(getCurrentTrip(), championId: getChampion()!.id!)
.do(onNext: { [weak self] trip in self?.saveCurrentTrip(trip) })
.filter { $0.id != nil }
Presumably, the above would be in a flatMap that catches errors...
Lastly, you should consider using RxFirebase