Authentication with Firebase suddenly stopped working


#1

I didn’t want to disturb any of you on this forum, but I’m having a problem since last sunday that I can’t manage to solve (even if I tried really hard!).
I’m using AngularFire2 5.0.0-rc.6 for my project, and everything worked until last week.
When I test the app on Ionic DevApp, I’m able to login, but as soon as it tries to fetch the records from the database, it throws the error “permission_denied at /segnalazioni” (as shown in the first screenshot below), even if most of the times it manages to fetch the data.
Then, when I try to push another page, it gives me the “Cannot read property ‘email’ of null” (second screenshot), even if this assignment is done in the constructor.

This are the rules set on the Realtime Database:

{
  "rules": {
		".read": "auth != null",
    ".write": "auth != null",
      
    "segnalazioni": {
      ".indexOn": ["user", "capo"]
     },
    "sorveglianti": {
      ".indexOn": ["id", "referente"]
     },
    "capi_servizio": {
      ".indexOn": ["id"]
     }
  }
}

I also tried to revert to the “testing rules”, where everybody can read or write (=true), and even if I can get the items, as soon as I check fire.auth.currentUser.email, it results as null.
So, I think that it is an authentication issue, but it’s strange, because everything was working fine before (I even tried a perfectly working apk build of the first days of April, and it too is now giving me error, not loading items if rules are applied or returning null in fire.auth.currentUser.email after login).

Here is my code, for login, items list, and app.component.ts:

import {Component, ViewChild} from '@angular/core';
import {AlertController, IonicPage, NavController, NavParams, Events} from 'ionic-angular';

import { MainElenco } from '../elenco/elenco';

import { AngularFireAuth } from 'angularfire2/auth';
import {AngularFireDatabase} from "angularfire2/database";
/**
 * Generated class for the LoginPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {

  @ViewChild('username') user;
  @ViewChild('password') pass;

  constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController, public fire: AngularFireAuth, public events: Events, public afDatabase: AngularFireDatabase) {
  }

  alert(message:string) {
    this.alertCtrl.create({
      title: 'Info',
      subTitle: message,
      buttons: ['OK']
    }).present();
  }


  async signIn(){
    this.fire.auth.signInWithEmailAndPassword(this.user.value, this.pass.value)
      .then( data => {
        console.log('Dati: ', this.fire.auth.currentUser.email)
        //Utente loggato
        //this.alert('Accesso eseguito correttamente');
        if(this.fire.auth.currentUser.emailVerified){
          this.events.publish('user:logged', this.fire.auth.currentUser.email);
          //this.afDatabase.database.goOnline();
          this.navCtrl.setRoot(MainElenco);
        }else{
          alert("Controlla la posta e verifica il tuo indirizzo email")
        }

      }).catch(error => {
        console.log('Errore: ',error)
      this.alert(error.message);
    });

  }

  register() {
    this.navCtrl.push('RegisterPage');
  }

  ionViewDidLoad() {
    //console.log('ionViewDidLoad LoginPage');
  }

}
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, MenuController, AlertController} from 'ionic-angular';

import { AngularFireAuth } from "angularfire2/auth";
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';

import { DettagliPage } from "../dettagli/dettagli";
import { FotoPage } from "../foto/foto";

import { Observable } from "rxjs/Observable";

import { Geolocation } from '@ionic-native/geolocation';


@IonicPage()
@Component({
  selector: 'page-elenco',
  templateUrl: 'elenco.html',
})
export class MainElenco {
  email: string;

    itemsRef: AngularFireList<any>;
    items: Observable<any []>;

    constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController, public fire: AngularFireAuth, public afDatabase: AngularFireDatabase, public geolocation: Geolocation) {
      this.email = fire.auth.currentUser.email;
      this.itemsRef = afDatabase.list('segnalazioni');
      this.items = afDatabase.list('segnalazioni', ref => ref.orderByChild('user').equalTo(this.email)).valueChanges();
  }

  alert(message:string) {
    this.alertCtrl.create({
      title: 'Info',
      subTitle: message,
      buttons: ['OK']
    }).present();
  }

  itemSelected(item: Observable<any>) {
    this.navCtrl.push(DettagliPage, {dettaglio: item});
  }

  fabClick(){
      alert(this.fire.auth.currentUser.email);
      this.navCtrl.push(FotoPage);
  }

  ionViewDidLoad() {

  }

}
import { Component, ViewChild } from '@angular/core';
import { Nav, Platform, MenuController, Events } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireDatabase } from 'angularfire2/database';

import { HomePage } from '../pages/home/home';
import { MainElenco } from '../pages/elenco/elenco';
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  //rootPage:any = HomePage;
  email: string;
  rootPage:any;
  pagine_utente: Array<{title: string, component: any}>;
  pagine_operatore: Array<{title: string, component: any}>;

  constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, public fire: AngularFireAuth, public menuCtrl: MenuController, public events: Events, public afDatabase: AngularFireDatabase) {
    this.initializeApp();

    
    const unsubscribe = fire.auth.onAuthStateChanged(user => {
      if (!user) {
        this.rootPage = HomePage;
        unsubscribe();
      } else {
        this.email = fire.auth.currentUser.email;
        this.events.publish('user:logged', fire.auth.currentUser.email);
        this.rootPage = MainElenco;
        unsubscribe();
      }
    });

    events.subscribe('user:logged', (user) => {
      this.email = user;
    });
  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      this.statusBar.styleDefault();
      this.splashScreen.hide();
    });
  }

  logout(){
    this.fire.auth.signOut();
    console.log("Logout")
    this.menuCtrl.toggle();
    this.nav.setRoot(HomePage);
  }
}

I know that the code is a bit of a mess, but I started learning Ionic 2 months ago, without any prior JavaScript/Angular experience.
Thanks to anybody who can give me a hint to solve this issue!


#2

I created a new project on Firebase (so, a new database and a new set of keys), and it started working again (after that, I also used “npm update” in the project folder, and it also updated both angularfire2 and firebase plugins).
So, I suppose the problem is on the server side of the project but, apart from the rules (pasted below), there are no settings that (to me) can explain the issue that I had (and, moreover, I fear it might happen again!).
Any thoughts?

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null",
      
      "segnalazioni": {
      ".indexOn": ["user", "capo"]
     },
    "sorveglianti": {
      ".indexOn": ["id", "referente"]
     },
    "capi_servizio": {
      ".indexOn": "id"
     }
  }
}