Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
组合和筛选QueryFirebase的唯一密钥_Firebase_Rxjs_Observer Pattern_Geofire - Fatal编程技术网

组合和筛选QueryFirebase的唯一密钥

组合和筛选QueryFirebase的唯一密钥,firebase,rxjs,observer-pattern,geofire,Firebase,Rxjs,Observer Pattern,Geofire,我正在开发一个应用程序,在这个应用程序中,承包商可以说他们在特定的日期“可用”,每个承包商都有一个“位置”。雇主可以根据位置和可用性来搜索可用性 该位置基于GeoFire。这将返回可用承包商的$key 看起来是这样的: geoQueryContractor(radius, lat, lng) { const subject = new Subject(); this.fbGeoRef = firebase.database().ref('geofire') this

我正在开发一个应用程序,在这个应用程序中,承包商可以说他们在特定的日期“可用”,每个承包商都有一个“位置”。雇主可以根据位置和可用性来搜索可用性

该位置基于GeoFire。这将返回可用承包商的$key

看起来是这样的:

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

}
接下来,我可以通过搜索firebase节点获得可用性,该节点看起来像“/AvailForContractor/${timestamp}/$uid:true”

这就是它的工作原理,并返回其配置文件:

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();
}
我让这两个独立工作。我真的需要知道在第二个函数中返回的所有$key中,哪些是在第一个函数中按位置可用的。我只需要返回满足这两个条件的配置文件

我一直在摆弄CombineTest、mergeMap、LatestFrom和Filter,但我不知道如何用正确的方法来实现这一点

我的想法是,一旦我从第二个函数中获得密钥,将其与GeoFire observable结合,并过滤唯一密钥,然后执行这一部分:

    //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)
这是不完整的,但一个糟糕的尝试

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按如下方式踢出单个键:

3vAWWHaxHRZ94tc8yY08CH3QNQy3
H74INXGYWIMRUCATZLOGFKWJ6QD2

Firebase将推出一系列密钥:

[3vAWWHaxHRZ94tc8yY08CH3QNQy3, H74INXgYWIMrUcAtZloFGkwJ6Qd2, J9DHhg5VQrMpNyAN8ElCWyMWh8i2, fdZYKqqiL0bSVF66zGjBhQVu9Hf1  ]
最终的结果将是这些独特的组合,以接收的方式,我将使用得到的配置文件


有人能帮忙吗?谢谢

这是我的解决方案。我相信有更好的办法。更新:下面是更好的解决方案

static geoArray: Array<string> = [];

constructor(private af: AngularFire, private db: AngularFireDatabase) {

}

getAvailablitybyContractor(timestamp, radius, lat, lng) {

    const availContractorKeys$ = this.db.list(`/AvailForContractor/${timestamp}`);

    const AvailContractors$ = availContractorKeys$

        //maping each key
        .map(keysPerContractor => keysPerContractor.map(keyPerContractor => keyPerContractor.$key)
        .filter(key => ContractorService.geoArray.indexOf(key) > -1)

         //once we have each key, we can map it and create an fb object observable
        .map(keyPerContractor => this.db.object(`/users/${keyPerContractor}`)))

        //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();
}

geoQueryContractor(radius, lat, lng) {


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

        ContractorService.geoArray.push(key);

    });

}


}
getAvailablitybyContractor(timestamp) {

    let availContractorKeys$ = this.db.list(`/AvailForContractor/${timestamp}`);

    this.AvailContractors$ = availContractorKeys$

        //maping each key
        .map(keysPerContractor => keysPerContractor.map(keyPerContractor => keyPerContractor.$key))
        //Combine observable from GeoQuery
        .combineLatest(this.keys$, (fb, geo) => ([fb, geo]))
        // fb, geo are accessible individually
        // .filter method creates a new array with all elements that pass the test implemented by the provided function
        // key is now iteriable through geo.indexOf
        .map(([fb, geo]) => {
            return fb.filter(key => geo.indexOf(key) > -1)
        })
        .map(filteredKeys => filteredKeys.map(keyPerContractor => this.db.object(`/users/${keyPerContractor}`)))
        //now we got back an array of firebase object observables (fbojs) and we need to combine them in to one observable
        .mergeMap(fbojs => {
            return Observable.combineLatest(fbojs)
        })
        .do(console.log)

}

getGeoQuery(radius, lat, lng) {

    this.geoQuery = this.geoFire.query({
        center: [lat, lng],
        radius: radius
    });

}

geoQueryContractor() {

    return this.keys$ = Observable.create(observer => {

        var keys = new Array();

        this.geoQuery.on("key_entered", (key, location, distance) => {
            keys.push(key);
            observer.next(keys);
        });

    });

}