0
votes

I am creating an Ionic app and have implemented a Firebase login. The login all works well, however I want to check if a user is logged in before loading the initial root page.

If they are not logged in,it should show the tutorial, and if they are, it should show the main tabs view.

Currently the setting of the route page works, howveer you always see the tutorials page first, no matter where in the start up I place the authentication code - It shows for 1-2 seconds if logged in and then redirects. How can i make sure the check is made before displaying anything?

    import { Component, ViewChild } from '@angular/core';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { TranslateService } from '@ngx-translate/core';
import { Config, Nav, Platform } from 'ionic-angular';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';


import { FirstRunPage, MainPage } from '../pages/pages';
import { Settings } from '../providers/providers';
import { HostelMainPage } from '../pages/hostel-main/hostel-main';



@Component({
  template: `<ion-menu [content]="content">
    <ion-header>
      <ion-toolbar>
        <ion-title>Pages</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content>
      <ion-list>
        <button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
          {{p.title}}
        </button>
      </ion-list>
    </ion-content>

  </ion-menu>
  <ion-nav #content [root]="rootPage"></ion-nav>`
})
export class MyApp {
  rootPage = FirstRunPage;
  isAuthenticated: boolean =  false;

  @ViewChild(Nav) nav: Nav;

  pages: any[] = [
    { title: 'Tutorial', component: 'TutorialPage' },
    { title: 'Profile', component: 'ProfilePage'}
  ]

  constructor(private translate: TranslateService, 
              platform: Platform, 
              settings: Settings, 
              private config: Config, 
              private statusBar: StatusBar, 
              private splashScreen: SplashScreen,
              private fbAuth : AngularFireAuth) {
    platform.ready().then(() => {
      this.CheckAuth();
    })
    .then(() => {
      console.log('loading');
      this.statusBar.styleDefault();
      this.splashScreen.hide();
    });
    this.initTranslate();
  }

  CheckAuth(){
    console.log('Auth Check');
    this.fbAuth.auth.onAuthStateChanged((user) => {
      if(user){
        this.isAuthenticated = true;
        this.rootPage = MainPage;
      } else {
        this.isAuthenticated = false;
        this.rootPage = FirstRunPage;
      }
    })
  }

Even after checking to see which code is executed first, the output shows the execution is correct.

Pages.ts

// The page the user lands on after opening the app and without a session
export const FirstRunPage = 'TutorialPage';

// The main page the user will see as they use the app over a long period of time.
// Change this if not using tabs
export const MainPage = 'TabsPage';

// The initial root pages for our tabs (remove if not using tabs)
export const QRTab = 'QRPage';
export const ProfileTab = 'ProfilePage';
export const HostelTab = 'HostelMainPage';
2

2 Answers

3
votes

You should use a Splash page to run the basic authentication logic. This should be your ROOT page within the app.component file.

Instead of trying to run the auth logic in the app.component.ts file, create a page which will run this logic and redirect when ready so something like;

ionViewDidLoad() {
  this.angularFireAuth.authState
    .first()
    .subscribe(auth => {
      if (auth) {
        // Redirect to logged in page
      } else {
        // Redirect to logged out page
      }
    });
}

The page could just be a loading animation or something to show the user that something is processing in the background.

0
votes

You can resolve this by just not setting the root page instantly.

Instead of

export class MyApp {
  rootPage = FirstRunPage;
...

write

export class MyApp {
  rootPage: any;
....