Angularfire firestore keeps giving insufficient permissions when trying to save to db

Viewed 153

When i try to upload to cloud firestore, i keep getting the "FirebaseError: Missing or insufficient permissions"

these are my rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
   match /{document=**} {
      allow read: if request.auth.uid == request.auth.uid
      allow write:  if request.auth.uid == request.auth.uid
    }
  }
}

this is my service

import { Injectable } from '@angular/core';
import { User } from '../Models/Users';
import { AlertController } from '@ionic/angular';
import { AngularFireAuth } from '@angular/fire/auth';
import * as firebase from 'firebase/app';
import { AngularFirestore } from '@angular/fire/firestore';
import { first } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class FirebaseService {

  constructor(
    private auth : AngularFireAuth,
    private firestore : AngularFirestore,
    private altCtrl : AlertController
  ) { }



  isLoggedIn() {
    return this.auth.authState.pipe(first()).toPromise();
  }
  async login(email:string, password:string):Promise<any>{
    var result = await this.auth.signInWithEmailAndPassword(email, password);

    //var result = await firebase.auth().signInWithEmailAndPassword(email,password);
    if(result.user !== undefined ){
      var uid = result.user.uid;
      return uid;
    }else{
      return null;
    }
  }

  async createAccount(email:string,password:string, user:User):Promise<boolean>{
    try {
      var result = await this.auth.createUserWithEmailAndPassword(email,password);
      //var result = await firebase.auth().createUserWithEmailAndPassword(email,password);
      if(result.user != undefined){
        return true;
      }else{
        return false;
      }
    } catch (error) {
      throw error;
    }
  }


  async createUserDocument(user:User):Promise<boolean>{
    try {
      await this.login(user.email, user.password);
      var result = await this.isLoggedIn();
      if(result){
        await this.firestore.collection('Users').doc(user.first_name).set(user);
        //await firebase.firestore().collection("Users").add(user);
        return true;
      }else{
        return false;
      }


    } catch (error) {
      throw error;
      return false;
    }
  }


}

this is my app module

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { LoaderComponent } from './widgets/loader/loader.component';
import { SQLite } from '@ionic-native/sqlite/ngx';
import { IonicStorageModule } from '@ionic/storage-angular';
import { AuthGuard } from './Guards/auth.guard';
import { AutoLoginGuard } from './Guards/auto-login.guard';
import { AngularFireModule } from '@angular/fire';
import {  AngularFirestoreModule } from '@angular/fire/firestore';

import { FirebaseService } from '../app/Services/firebase.service';

//real information hidden for security
const config = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxx",
  projectId: "xxxxxxxxxxxxxxxxxxxxxxxxx",
  storageBucket: "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  messagingSenderId: "xxxxxxxxxxxxxxxxxxxxxxxxxx",
  appId: "xxxxxxxxxxxxxxxxxxxxxx",
  measurementId: "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
@NgModule({
  declarations: [
    AppComponent,
    LoaderComponent
  ],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    IonicStorageModule.forRoot(),
    AngularFireModule.initializeApp(config),
    AngularFirestoreModule,
    AngularFirestoreModule.enablePersistence(),
  ],
  providers: [
    {
      provide: RouteReuseStrategy,
      useClass: IonicRouteStrategy
    },
    AuthGuard,
    AutoLoginGuard,
    SQLite,
    SplashScreen,

    FirebaseService,

  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

the save to the database only works if the rules are set to if true.

In my cause, users are allowed to modify data as long as they have been authenticated

2 Answers

Well i found some kind of a solution. But i can't really explain why it works.

Solution: First i add private afAuth: AngularFireAuth to the constructor of a random component. It still dosn't work after that. But if i add this.afAuth.setPersistence(firebase.auth.Auth.Persistence.SESSION); or this.afAuth.signInWithPopup(new firebase.auth.GoogleAuthProvider()); anywhere (even if those lines get never called) inside that random Component the AuthService suddenly works and spits out all the data i want.

Details: https://github.com/angular/angularfire/issues/2864

Related