Firebase 如何使用rxfire和rxjs(或查询)连接两个Firestore查询

Firebase 如何使用rxfire和rxjs(或查询)连接两个Firestore查询,firebase,rxjs,google-cloud-firestore,rxfire,Firebase,Rxjs,Google Cloud Firestore,Rxfire,目标很简单:使用rxjs、rxfire和rnfirebase反应本机库连接两个firestore查询 我已经阅读了多篇关于连接查询的教程,但它们都会因不同的错误而失败 //收集数据的简单测试 从“rxfire/firestore”导入{collectionData}; this.myQuery=this.props.docRef.collection(`messages`)。其中('read','array contains',this.props.me.uid) collectionData(

目标很简单:使用
rxjs
rxfire
rnfirebase
反应本机库连接两个firestore查询

我已经阅读了多篇关于连接查询的教程,但它们都会因不同的错误而失败

//收集数据的简单测试
从“rxfire/firestore”导入{collectionData};
this.myQuery=this.props.docRef.collection(`messages`)。其中('read','array contains',this.props.me.uid)
collectionData(this.myQuery,'id').subscribe(docs=>console.log(docs))
//失败并出现错误:this.\u next不是函数。
或者

this.publicQuery=this.props.docRef.collection('messages')。其中('public','==',true)
this.myQuery=this.props.docRef.collection(`messages`)。其中('read','array contains',this.props.me.uid)
const myQuery$=new Rx.Subject();
const publicQuery$=new Rx.Subject();
this.myQuery.onSnapshot((querySnapshot)=>{
myQuery$.next(querySnapshot.docs.map(d=>d.data());
});
this.publicQuery.onSnapshot((querySnapshot)=>{
publicQuery$.next(querySnapshot.docs.map(d=>d.data());
});
const或query$=CombineTest(this.myQuery,this.publicQuery).switchMap((文档)=>{
var[1,2]=单据;
var组合=1.concat(2);
可观测的(组合)返回Rx;
})
orQuery$.subscribe((结果)=>{
console.log('>>>',result)
})
//TypeError:undefined不是函数(靠近…开关映射)

我如何才能成功地加入两个firestore查询(或)?

您已经非常接近解决方案了。让我们一步一步地讨论这些问题

首先,不必创建一个
主题
,只需从
onSnapshot
转换结果即可。与此相反:

this.myQuery.onSnapshot((querySnapshot) => {
    myQuery$.next(querySnapshot.docs.map(d => d.data()))
});
我们可以使用“可管道转换运算符”实现同样的效果:

const myQuery$ = this.myQuery.onSnapshot.pipe(
    map(querySnapshot => querySnapshot.docs.map(d => d.data()))
);
另一个查询也是如此:

const publicQuery$ = this.publicQuery.onSnapshot.pipe(
    map(querySnapshot => querySnapshot.docs.map(d => d.data())
);
其次,要连接这两个查询,
combinelateest
确实是正确的创建函数

但是,您的错误可能是因为您使用了更新的RxJS版本,该版本不再支持“fluent”操作符()。从RxJS 6开始,它们已被“可管道操作员”取代。例如,
myObs$.map(…)
已成为
myObs$.pipe(map(…)
。教程可能使用RxJS的旧版本,其中第一个版本仍然是可能的

此外,如果内部可观察对象只是操作符的一个,则不必使用
switchMap
。在这种情况下,使用
map
操作符就足够了,该操作符的行为相同

使用新的RxJS 6+语法和
map
,组合如下:

const orQuery$ = combineLatest(myQuery$, publicQuery$).pipe(
    map(([one, two]) => one.concat(two))
)
代码的其余部分应该是正确的

旁注:请记住,SQL中代码的等价物是
UNION
(而不是
JOIN
)。为了通过编程方式
连接
,您需要将结果集A的每个对象与结果集B的每个对象组合起来,并为每对对象创建一个连接对象。这样一个无键
外部连接的函数将如下所示(放置在
映射
管道中):

如果希望有一个无重复对象的
UNION
,请仅从
two
中选择列表
one
中没有匹配主键的项。这将是您的映射函数:

one.concat(two.filter(twoItem => !one.some(oneItem => oneItem.id == twoItem.id)))
演示:可以在此处找到完整的、使用上述代码的工作演示和模拟FireStore:


您使用的是什么版本的RxJS?您正在使用rxjs compat吗?
one.concat(two.filter(twoItem => !one.some(oneItem => oneItem.id == twoItem.id)))