civicboy 13
civicboy 13

Reputation: 31

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

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

Upvotes: 3

Views: 194

Answers (2)

roboalex2
roboalex2

Reputation: 80

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

Upvotes: 1

Nicolas
Nicolas

Reputation: 491

I don't know if it is from Angular 12 or from firebase. I solved it by downgrading firebase to version 8.3.0

https://github.com/angular/angularfire/issues/2857

Upvotes: 2

Related Questions