I am using Ionic2 with Angularfire2 to access Firebase Authentication.
I access the following 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;
});
}
Also, in Firebase Authentication, I have the following Realtime Database Rules:
"rules": {
".read": "auth != null",
".write": "auth != null",
}
Problem
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:
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.
Question
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 : I never used firebase , I use AWS so the firebase code might not be precise, we discuss about it .
Here is my version:
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
)
)
)
);
}
Auth Service
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);
}
});
}
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.
UPDATE :
Refactoring other answer:
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))
]
);
}
Except when you are caching response using Subject never use subscribe inside service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With