Reputation: 3314
I'm trying to set permissions so a user with a given email address can only read a document with a matching docId.
This is the collection of documents:
/cats/[email protected]
/cats/[email protected]
/cats/[email protected]
The following works perfectly in the "Rules Playground", but it always ends up returning nothing in my Angular app.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /cats/{catDocId} {
allow read: if request.auth.token.email.lower() == catDocId;
allow write: if false;
}
}
}
Here is the app code:
myPage.component.ts:
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
// ...
cats: Observable<any[]>;
// ...
ngOnInit(): void {
this.afAuth.authState.subscribe(user => {
this.cats = this.firestore.collection('cats').valueChanges();
});
}
myPage.component.html:
<ul>
<li class="text" *ngFor="let cat of cats | async">
{{cat.name}}, {{cat.color}}, {{cat.favoriteFood}}
</li>
</ul>
Any ideas where this is going wrong? Thanks.
Upvotes: 0
Views: 70
Reputation: 83048
From your comment:
So it seems I'm trying to use the rules as a filter. Is there a simple way to grant read access to a single doc based on the user's token data, namely their email address?
You just need to use the User
object in order to get the user's email. I'm not really versed in angularfire
but the following code (from the angularfire doc on Authentication) shows how to get the displayName
property. You should do the same with the email
property. Then you should directly query the document, as explained here, since you have the entire DocumentReference
.
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import firebase from 'firebase/app';
@Component({
selector: 'app-root',
template: `
<div *ngIf="auth.user | async as user; else showLogin">
<h1>Hello {{ user.displayName }}!</h1>
<button (click)="logout()">Logout</button>
</div>
<ng-template #showLogin>
<p>Please login.</p>
<button (click)="login()">Login with Google</button>
</ng-template>
`,
})
export class AppComponent {
constructor(public auth: AngularFireAuth) {
}
login() {
this.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
logout() {
this.auth.signOut();
}
}
Upvotes: 1