Javascript Firebase如何取消订阅
我正在使用Javascript Firebase如何取消订阅,javascript,firebase,ionic-framework,firebase-authentication,angularfire2,Javascript,Firebase,Ionic Framework,Firebase Authentication,Angularfire2,我正在使用Ionic2和Angularfire2访问Firebase身份验证 我访问以下rxjs/Observable: chats.ts this.firelist = this.dataService.findChats(); this.subscription = this.firelist.subscribe(chatItems => { ... }); ngDestroy() { this.subscription.unsubscribe();
Ionic2
和Angularfire2
访问Firebase身份验证
我访问以下rxjs/Observable
:
chats.ts
this.firelist = this.dataService.findChats();
this.subscription = this.firelist.subscribe(chatItems => {
...
});
ngDestroy() {
this.subscription.unsubscribe();
}
findChats(): Observable<any[]> {
this.firebaseDataService.findChats().forEach(firebaseItems => {
...
observer.next(mergedItems);
});
}
findChats(): Observable<any[]> { // populates the firelist
return this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
}).map(items => {
const filtered = items.filter(
item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
);
return filtered;
});
}
dataService.ts
this.firelist = this.dataService.findChats();
this.subscription = this.firelist.subscribe(chatItems => {
...
});
ngDestroy() {
this.subscription.unsubscribe();
}
findChats(): Observable<any[]> {
this.firebaseDataService.findChats().forEach(firebaseItems => {
...
observer.next(mergedItems);
});
}
findChats(): Observable<any[]> { // populates the firelist
return this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
}).map(items => {
const filtered = items.filter(
item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
);
return filtered;
});
}
问题
当用户登录时(即,auth!=null
),此操作非常有效,但一旦用户注销,并且auth==null
,我就会出现以下错误:
错误:未捕获(承诺中):错误:权限\u在/聊天时被拒绝:
客户端没有访问所需数据的权限。错误:
权限\在/聊天时被拒绝:客户端没有访问权限
所需的数据
问题
正如您在上面的代码中所看到的,我尝试从Firebase身份验证服务
取消订阅
,但一定是做得不正确。如果有人能建议我应该如何取消订阅
,以停止我的应用程序查询Firebase数据库,我将非常感谢您的帮助。这不是问题的确切答案,但我的论点是,如果我们以其他方式这样做,我们将永远不会遇到这个问题
注:我从未使用过firebase,我使用的是AWS,所以firebase代码可能不精确,我们对此进行了讨论
以下是我的版本:
findChats(): Observable<any[]> { // populates the firelist
return
this.authService.getCurrentUser()
.flatMap(user => user === null ?
Observable.empty():
this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
})
.map(items =>
return items.filter(
item => (
item.memberId1 === this.me.uid ||
item.memberId2 === this.me.uid
)
)
)
);
}
代码非常原始,但我希望它传达了这个想法。在这里,我观察用户身份验证状态并执行flatMap
获取数据。如果用户注销,身份验证状态将更改为null,因此UI中的数据将更改为空列表。即使用户没有注销,仍然无法看到数据
更新: 重构其他答案:
findChats(){
return Observable.merge(
this.firebaseDataService
.findChats()
.flatMap(chats => Observable.from(chats)),
this.localDataService
.findChats()
.flatMap(chats => Observable.from(chats))
)
.filter(chat => !!chat)
.toArray()
.map(chats => [
...chats.sort(
(a, b) =>
parseFloat(a.negativtimestamp) - parseFloat(b.negativtimestamp))
]
);
}
除非您使用
Subject
缓存响应,否则切勿使用subscribe
内部服务 取消订阅功能正常。问题是,我使用的以下函数由于某种原因导致它订阅了两次:
findChats(): Observable<any[]> {
return Observable.create((observer) => {
this.chatSubscription2 = this.firebaseDataService.findChats().subscribe(firebaseItems => {
this.localDataService.findChats().then((localItems: any[]) => {
let mergedItems: any[] = [];
if (localItems && localItems != null && firebaseItems && firebaseItems != null) {
for (let i: number = 0; i < localItems.length; i++) {
if (localItems[i] === null) {
localItems.splice(i, 1);
}
}
mergedItems = this.arrayUnique(firebaseItems.concat(localItems), true);
} else if (firebaseItems && firebaseItems != null) {
mergedItems = firebaseItems;
} else if (localItems && localItems != null) {
mergedItems = localItems;
}
mergedItems.sort((a, b) => {
return parseFloat(a.negativtimestamp) - parseFloat(b.negativtimestamp);
});
observer.next(mergedItems);
this.checkChats(firebaseItems, localItems);
});
});
});
}
findChats():可观察{
返回可观察的。创建((观察者)=>{
this.chatSubscription2=this.firebaseDataService.findChats().subscribe(firebaseItems=>{
this.localDataService.findChats()。然后((localItems:any[])=>{
让mergedItems:any[]=[];
if(localItems&&localItems!=null&&firebaseItems&&firebaseItems!=null){
for(设i:number=0;i{
返回parseFloat(a.negativetimestamp)-parseFloat(b.negativetimestamp);
});
观察员:下一个(合并);
检查聊天(firebaseItems、LocaliItems);
});
});
});
}
出于某种原因,上面的第三行被调用了两次(即使函数只被调用了一次)。这将创建第二个订阅
,第一个订阅
永远不会取消订阅
因此,可观察的
的创建似乎是不正确的。我不知道是什么;但是,这是创建可观察的的正确方法。为什么不执行此.firelist.unsubscribe()
Hi Skeptor,谢谢您的反馈this.firelist
是一个rxjs/ObservableI从不退订,因此不确定语法。但在我看来,您需要监视每个http调用的身份验证对象状态,而不是取消订阅。我将提供一种不同的方式来编写相同的代码,以及我在应用程序中的操作方式。(我使用aws,但它们几乎相同)谢谢你,感谢你的帮助。如果黑客登录并试图访问其他用户的消息,会发生什么?这就是Firebase规则派上用场的地方。您只能允许访问与用户uid
匹配的消息。您可以执行以下操作:`“chat”:{“$key”:{.read”:“data.child('memberId1').val()==auth.uid | | | data.child('memberId2').val()==auth.uid | | | true”,“.write”:“data.child('memberId1').val()==auth.uid | | | | data.child('memberId2').val()==auth.uid | | | | true”},`我已经发布了一个关于如何创建Observable
的问题,以便这里只有一个订阅:您不应该使用Observable.create
。使用map进行一些转换后,直接返回this.firebaseDataService
。我不知道该怎么做,因为使用可观察的的列表当前正在订阅它,也就是说,它需要动态更新。我将使用重构方法更新我的答案谢谢您的关注