I'm working on an app where a contractor can say that they are "available" on specific days and each contractor has a "location". An employer can search for availability based off of location and availability.
The location is based off of GeoFire. This returns the $key of the contractors that are available.
That looks like this:
geoQueryContractor(radius, lat, lng) {
const subject = new Subject();
this.fbGeoRef = firebase.database().ref('geofire')
this.geoFire = new GeoFire(this.fbGeoRef);
this.geoFire.ref();
this.geoQuery = this.geoFire.query({
center: [lat, lng],
radius: radius
});
this.geoQuery.on("key_entered", function(key, location, distance) {
subject.next(key);
});
return subject.asObservable();
}
Next, I can get the availablity by searching the firebase node that looks like this "/AvailForContractor/${timestamp}/$uid:true"
This is how that works and it returns their profile:
getAvailablitybyContractor(timestamp) {
const availContractorKeys$ = this.db.list(`/AvailForContractor/${timestamp}`);
const AvailContractors$ = availContractorKeys$
//maping each key
.map(keysPerContractor => keysPerContractor
//once we have each key, we can map it and create an fb object observable
.map(keyPerContractor => this.db.object(`/users/${keyPerContractor.$key}`)))
//now we got back an array of firebase object observables (fbojs) and we need to combine them in to one observable
.mergeMap(fbojs => Observable.combineLatest(fbojs))
.do(console.log)
AvailContractors$.subscribe();
}
I have these 2 working independently of each other. I really need to know out of all the $key's returned in the 2nd function, which ones are available by location in the 1st function. I only need to return the profiles where those 2 criteria are met.
I've been messing around with CombineLatest, mergeMap, withLatestFrom and Filter but I can't figure out how to do this the proper way.
My thought is that once I get the keys from the 2nd function, combine it with the GeoFire observable and filter unique keys, then do this part:
//once we have each key, we can map it and create an fb object observable
.map(keyPerContractor => this.db.object(`/users/${keyPerContractor.$key}`)))
//now we got back an array of firebase object observables (fbojs) and we need to combine them in to one observable
.mergeMap(fbojs => Observable.combineLatest(fbojs))
.do(console.log)
This is not complete but a poor attempt...
getAvailablitybyContractor(timestamp, radius, lat, lng) {
const availContractorKeys$ = this.db.list(`/AvailForContractor/${timestamp}`);
//when we get back the keys, we are going to switch to another obeservables
const AvailContractors$ = availContractorKeys$
//maping each key
.map(keysPerContractor => keysPerContractor
.map(keyPerContractor => keyPerContractor.$key))
.combineLatest(this.geoQueryContractor(radius, lat, lng))
// .withLatestFrom(this.geoQueryContractor(radius, lat, lng), (keysPerContractor, geo) => ( [keysPerContractor, geo] ))
//once we have each key, we can map it and create an fb object observable
// .map(keyPerContractor => this.db.object(`/users/${keyPerContractor.$key}`)))
// //now we got back an array of firebase object observables (fbojs) and we need to combine them in to one observable
// .mergeMap(fbojs => Observable.combineLatest(fbojs))
.do(console.log)
AvailContractors$.subscribe();
}
GeoFire kicks out individual keys like this by the way:
3vAWWHaxHRZ94tc8yY08CH3QNQy3
, H74INXgYWIMrUcAtZloFGkwJ6Qd2
, etc.
Firebase will kick out an array of keys:
[3vAWWHaxHRZ94tc8yY08CH3QNQy3, H74INXgYWIMrUcAtZloFGkwJ6Qd2, J9DHhg5VQrMpNyAN8ElCWyMWh8i2, fdZYKqqiL0bSVF66zGjBhQVu9Hf1 ]
End result would be the unique combination of those to in an RX way which I would use to get the profiles.
Can anyone help? Thanks!