I'm working on testing Firestore rules via AngularFire and Firebase Emulators.
My firestore rule is very simple and only checks whether the user logged in or not.
And what problem is that it isn't allowed any user reaches the Firestore, despite the user is after authed.
But when I don't use Emulator(i.e. use real Firestore ), it is allowed.
So I wonder whether there are additional settings when I use Emulator? Please help me!
Browser console:
core.js:6210 ERROR Error: Uncaught (in promise): FirebaseError: [code=permission-denied]: PERMISSION_DENIED:
false for 'create' @ L5
My environment:
- firebase-tools: 9.8.0
- Angular: 11.2.12
- @angular/fire: 6.1.4
My Firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
app.module.ts:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFireAuthModule,
AngularFirestoreModule,
],
providers: [
{ provide: USE_AUTH_EMULATOR, useValue: environment.useEmulators ? ['localhost', 9099] : undefined },
{ provide: USE_DATABASE_EMULATOR, useValue: environment.useEmulators ? ['localhost', 9000] : undefined },
{ provide: USE_FIRESTORE_EMULATOR, useValue: environment.useEmulators ? ['localhost', 8080] : undefined },
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html:
<button (click)="onLoginButtonClick()">change status(current: {{status}})</button><br>
app.component.ts:
export class AppComponent {
status = 'not logged in';
constructor(
private afAuth: AngularFireAuth,
private afStore: AngularFirestore
) {
this.afAuth.authState
.subscribe((user) => {
if ( user != null ) {
// If user logged in, then add new data.
this.afStore
.collection('test_data')
.doc(user.uid)
.set({data: 'test data'}); // this causes error!
}
});
}
async onLoginButtonClick(): Promise<void>{
if ( this.status === 'not logged in'){
const provider = new firebase.auth.GoogleAuthProvider();
await this.afAuth.signInWithPopup(provider);
this.status = 'logged in';
}
else{
await this.afAuth.signOut();
this.status = 'not logged in';
}
}
}