Ionic 4 tabs color do not change when establishing rootPage conditionally in app.component.ts


#1

Hi, I have a problem with the color of the tabs, it does not change when you press one. This occurred after establishing rootPage dynamically if the user is logged in with (firebase auth). Returning the code in app.component.ts by setting rootPage: TabsPage Works correctly. The only problem is that it does not change the color, if it sends to the correct view when pressing, but the color “active” stays in a previous one or only stays in one and no longer changes. It changes when you press a view button eg. open a modal.

Ionic info


Previous Working app.component.ts

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Firebase } from '@ionic-native/firebase';
import { AngularFireDatabase } from 'angularfire2/database';
import { Subject } from 'rxjs/Subject';
import { tap } from 'rxjs/operators';
import { timer } from 'rxjs/observable/timer';
import { ToastController } from 'ionic-angular';

import { TabsPage } from '../pages/tabs/tabs';

declare var Conekta: any;

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage: any = TabsPage;
  showSplash = true;

  constructor(
    public afDB: AngularFireDatabase,
    statusBar: StatusBar,
    splashScreen: SplashScreen,
    private firebase: Firebase,
    public platform: Platform,
    public toastCtrl: ToastController
  ) {
    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.
      statusBar.styleDefault();
      splashScreen.hide();
      timer(6000).subscribe(() => this.showSplash = false);
      try {
        this.initializeFirebase();
      } catch (error) {
        alert(error);
      }

    });
  }

  initializeFirebase() {
    if (!this.platform.is("core")) {
      this.firebase.subscribe("all");
      this.platform.is('android') ? this.initializeFirebaseAndroid() : this.initializeFirebaseIOS();
    }
  }
  initializeFirebaseAndroid() {
    try {
      this.firebase.getToken().then(token => { this.saveTokenToDB(token) });
      this.firebase.onTokenRefresh().subscribe(token => { this.saveTokenToDB(token) })
      this.subscribeToPushNotifications();
    } catch(error) {
      alert(error);
    }
  }

  initializeFirebaseIOS() {
    this.firebase.grantPermission()
      .then(() => {
        this.firebase.getToken().then(token => { this.saveTokenToDB(token) });
        this.firebase.onTokenRefresh().subscribe(token => { this.saveTokenToDB(token) })
        this.subscribeToPushNotifications();
      })
      .catch((error) => {
        this.firebase.logError(error);
      });
  }

  subscribeToPushNotifications() {
    this.firebase.onNotificationOpen().subscribe((response) => {
      if (response.tap) {
        //Received while app in background (this should be the callback when a system notification is tapped)
        //This is empty for our app since we just needed the notification to open the app
        alert(JSON.stringify(response));
        this.firebase.setScreenName("Messages");
      } else {
        //received while app in foreground (show a toast)
        alert(response.body);
        let toast = this.toastCtrl.create({
          message: response.body,
          duration: 3000
        });
        toast.present();
      }
    });
  }

  saveTokenToDB(token) {
    this.afDB.database.ref('devices').push(
      token
      , function (error) {
        if (error) {
          alert('Error 2: ' + error)
          return
        }
      });
  }
}

Actual Not working app.component.ts

import { Component } from '@angular/core';
import { App, Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Firebase } from '@ionic-native/firebase';
import { AngularFireDatabase } from 'angularfire2/database';
import { AuthProvider } from '../providers/auth/auth';
import { Subject } from 'rxjs/Subject';
import { tap } from 'rxjs/operators';
import { timer } from 'rxjs/observable/timer';
import { ToastController } from 'ionic-angular';
import { LoginPage } from '../pages/login/login';
import { TabsPage } from '../pages/tabs/tabs';

declare var Conekta: any;

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage: any;
  showSplash = true;

  constructor(
    public app: App,
    public afDB: AngularFireDatabase,
    statusBar: StatusBar,
    splashScreen: SplashScreen,
    private firebase: Firebase,
    public platform: Platform,
    public toastCtrl: ToastController,
    public AuthProvider:AuthProvider
  ) {
    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
      timer(5000).subscribe(() => this.showSplash = false);
      let that = this;
      try {
        this.AuthProvider.afAuth.auth.onAuthStateChanged(function (user) {
          if (user) {
            that.initializeFirebase();
            that.app.getActiveNav().setRoot(TabsPage); //to the page where user navigates after login
            // User is signed in.
          } else {
            that.app.getActiveNav().setRoot(LoginPage); // to the login page as user is not logged in
            // No user is signed in.
          }
        });
        
      } catch (error) {
        alert(error);
      }

    });
  }

  initializeFirebase() {
    if (!this.platform.is("core")) {
      this.firebase.subscribe("all");
      this.platform.is('android') ? this.initializeFirebaseAndroid() : this.initializeFirebaseIOS();
    }
  }
  
  initializeFirebaseAndroid() {
    try {
      this.firebase.getToken().then(token => { this.saveTokenToDB(token) });
      this.firebase.onTokenRefresh().subscribe(token => { this.saveTokenToDB(token) })
      this.subscribeToPushNotifications();
    } catch(error) {
      alert(error);
    }
  }

  initializeFirebaseIOS() {
    this.firebase.grantPermission()
      .then(() => {
        this.firebase.getToken().then(token => { this.saveTokenToDB(token) });
        this.firebase.onTokenRefresh().subscribe(token => { this.saveTokenToDB(token) })
        this.subscribeToPushNotifications();
      })
      .catch((error) => {
        this.firebase.logError(error);
      });
  }

  subscribeToPushNotifications() {
    this.firebase.onNotificationOpen().subscribe((response) => {
      if (response.tap) {
        //Received while app in background (this should be the callback when a system notification is tapped)
        //This is empty for our app since we just needed the notification to open the app
      } else {
        //received while app in foreground (show a toast)i
        let toast = this.toastCtrl.create({
          message: response.body,
          duration: 3000
        });
        toast.present();
      }
    });
  }

  saveTokenToDB(tokenId) {
    let devToken = {
      token: tokenId,
      date: new Date().getTime()
    }
    this.afDB.database.ref('devices/'+this.AuthProvider.afAuth.auth.currentUser.uid).set(
      devToken
      , function (error) {
        if (error) {
          alert('Error 2: ' + error)
          return
        }
      });
  }
}

tabs.ts

import { Component, ViewChild } from '@angular/core';
import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';
import { HomePage } from '../home/home';
import { Messages } from '../messages/messages';
import {AngularFireAuth} from 'angularfire2/auth';
import { NavController, Tabs } from 'ionic-angular';
import { ProyectosPage } from '../proyectos/proyectos';

@Component({
  templateUrl: 'tabs.html'
})


export class TabsPage {
  tab1Root = HomePage;
  tab2Root = AboutPage;
  tab3Root = ContactPage;
  tab4Root = Messages;
  tab5Root = ProyectosPage;
  tab1badAge = 3;
  
  constructor(private afAuth: AngularFireAuth, public navCtrl: NavController) {

  }

  ionViewDidLoad() {
  }
}

tabs.html

<ion-tabs [selectedIndex]="index">
  <ion-tab [root]="tab1Root" tabTitle="Explorar" tabBadge="" tabIcon="compass"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Trabajos" [tabBadge]="tab1badAge" tabIcon="list-box"></ion-tab>
  <ion-tab [root]="tab5Root" tabTitle="Proyectos" tabBadge="" tabIcon="bookmarks"></ion-tab>
  <ion-tab [root]="tab4Root" tabTitle="Mensajes" tabBadge="" tabIcon="chatbubbles" tabsHideOnSubPages="true"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Perfil" tabBadge="" tabIcon="person"></ion-tab>
</ion-tabs>

I have tried to create a function when loading each view by pressing a tab. simulating a button but I do not want to resort to that disgusting solution.


#2

this was the problem

settting out the rootPage out of ready

try {
      const unsubscribe = this.AuthProvider.afAuth.auth.onAuthStateChanged(user => {
        if (user) {
          this.initializeFirebase();
          this.rootPage = TabsPage;
          unsubscribe();
        } else {
          this.rootPage = LoginPage;
          unsubscribe();
        }
      });
      
    } catch (error) {
      alert(error);
    }
    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
      timer(5000).subscribe(() => this.showSplash = false);
    });