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
。我不知道该怎么做,因为使用
可观察的
的列表当前正在订阅它,也就是说,它需要动态更新。我将使用重构方法更新我的答案谢谢您的关注