Firebase如何退订 [英] Firebase how to unsubscribe
问题描述
我正在将 Ionic2
与 Angularfire2
一起使用,以访问 Firebase身份验证
.
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:
错误错误:未捕获(承诺):错误:/chat中的权限被拒绝:客户端没有访问所需数据的权限.错误:/chat上的Permission_denied:客户端无权访问所需的数据.
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
来获取数据.如果用户注销,身份验证状态将更改为null,因此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屋!