Firebase 如何取消订阅 [英] Firebase how to unsubscribe

查看:28
本文介绍了Firebase 如何取消订阅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Ionic2Angularfire2 来访问 Firebase Authentication.

I am using Ionic2 with Angularfire2 to access Firebase Authentication.

我访问以下rxjs/Observable:

chats.ts

  this.firelist = this.dataService.findChats();
  this.subscription = this.firelist.subscribe(chatItems => {
     ...
  });

  ngDestroy() {
    this.subscription.unsubscribe();
  }

dataService.ts

findChats(): Observable<any[]> {
        this.firebaseDataService.findChats().forEach(firebaseItems => {
           ...
           observer.next(mergedItems);
        });
}

firebaseDataService.ts

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

此外,在 Firebase 身份验证中,我有以下实时数据库规则:

Also, in Firebase Authentication, I have the following Realtime Database Rules:

  "rules": {
      ".read": "auth != null",
      ".write": "auth != null",
  }

问题

这在用户登录时非常有效(即 auth != null),但是一旦用户注销,并且 auth == null,我得到以下错误:

This works perfectly while a user is logged in (i.e. auth != null), but a soon as a user logs out, and auth == null, I get the following error:

错误错误:未捕获(承诺):错误:permission_denied at/chat:客户无权访问所需数据.错误:permission_denied at/chat: 客户端无权访问所需的数据.

ERROR Error: Uncaught (in promise): Error: permission_denied at /chat: Client doesn't have permission to access the desired data. Error: permission_denied at /chat: Client doesn't have permission to access the desired data.

问题

正如您在上面的代码中看到的,我尝试从 Firebase 身份验证服务中取消订阅,但一定是操作不正确.如果有人可以建议我应该如何取消订阅以停止我的应用查询 Firebase 数据库,我将不胜感激.

As you can see in the above code, I try to unsubscribe from the Firebase Authentication Service, but must be doing it incorrectly. If anyone can advise how I should unsubscribe in order to stop my app querying the Firebase database, I would appreciate the help.

推荐答案

这不是问题的确切答案,但我的论点是,如果我们这样做,我们将永远不会遇到这个问题.

This is not an exact answer to the question, but my argument is we will never come to this issue if we do this other way.

P.S:我从来没有用过 firebase ,我用的是 AWS 所以 firebase 代码可能不准确,我们讨论一下.

P.S : I never used firebase , I use AWS so the firebase code might not be precise, we discuss about it .

这是我的版本:

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

身份验证服务

public currentUser = new BehaviorSubject(null);

constructor(){

    firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
           // User is signed in.
           currentUser.next(user);
        } else {
         // No user is signed in.
           currentUser.next(null);
        }
    });

}    

代码很原始,但我希望它传达了这个想法.在这里,我观察用户身份验证状态并执行 flatMap 以获取数据.如果用户注销,身份验证状态更改为空,因此在 UI 数据中更改为空列表.即使用户没有注销,他仍然看不到数据.

The code is very raw but I hope it conveys the idea. Here I am observing on the user authentication status and doing flatMap to fetch data. If user logs out, auth status change to null so in the UI data changes to empty list. Even if the user is not logged out , still he cannot see the data.

更新:

重构其他答案:

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.

Except when you are caching response using Subject never use subscribe inside service.

这篇关于Firebase 如何取消订阅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆