I have a 'Teams' collection in Firestore. A team document will include a team_users
map field where userID: true
if they are a part of that team.
I have a query in a service that returns and displays all team documents where the logged in user id matches an ID within the team_users
field.
getTeamsList(user_id: string) {
this.teamsCollection = this.afs.collection<any>(`teams`, ref => ref.where(`team_users.${user_id}`, "==", true))
this.teams = this.teamsCollection.snapshotChanges().pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
}))
).pipe(shareReplay());
}
What I need to achieve is a route guard that performs the following:
Team A
, but have since left, they should not be able to access this route and should instead be redirected back to the url of /teams
/teams
listing urlNote: A user can be a part of multiple teams. If the user was a part of Team A, B and C and has bookmarks for pages in Team A, but has since left, the route guard should prevent them from accessing any pages that were a part of Team A, but still allow access to Team B and C pages.
Does this mean that:
Any help would be greatly appreciated.
A user is on /teams page displaying teams (You don't need a guard on this route). When a user clicks on one of the teams navigate to /teams/teamID (Now this route needs a guard to prevent a user that doesn't belong to teamID from accessing it. To set the guard do this:
isTeamMember(userId: string, teamId: string): Observable < Boolean > {
return this.firestore.doc < any > (`teams/${teamId}`).snapshotChanges().pipe(
map(value => value.payload.data().team_users[userId] === true));
}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable < boolean > | Promise < boolean > | boolean {
return this.firestoreService.isTeamMember(userIdFromWhereYouStoreYourCurrentUser, teamIdFromTheCurrentUrl).pipe(map(isTeamMember => {
if (isTeamMember) {
return true;
} else {
//Add your not team member logic here, eg Stay in the current route, may be show an error message
return false;
}
}),
take(1));
}