How to fix push not found in Navcontroller ionic - firebase

I am getting the following error while using this code. I have also tried to change the push function to setRoot and the same error still persists.
I want to navigate to the home page which is the login page in case the user is not signed in but unable to do so.
The console shows that it entered the if statement but the navctrl command is not getting executed.
MyApp_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'push' of undefined
This my code:
import { Component, ViewChild } from '#angular/core';
import { IonicPage, NavController, NavParams, AlertController} from 'ionic-angular';
import * as firebase from 'firebase/app';
import { HomePage } from '../home/home';
/**
* Generated class for the MainPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-main',
templateUrl: 'main.html',
})
export class MainPage {
constructor(public navParams: NavParams, public alertCtrl: AlertController, public navController:NavController) {
}
ionViewDidLoad() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
console.log(user);
console.log('entered in if');
// User is signed in.
} else {
console.log(user);
console.log('entered in else');
this.navController.push(HomePage);
// No user is signed in.
}
});
console.log('ionViewDidLoad MainPage')
}
}

Related

ionic 4 + firebaseX stopped receiving push (android and ios)

My app has stopped from receiving push notifications.
I don't know what else I can do to check it.
It was working a few months ago
Stopped working for both iOS and Android
Installed and checked app permissions many times
Firebase is initializing, getting token and registering in my database fine
Tried test messages on Firebase console with generated token and it didn't work as well
Here is my notification.service.ts code:
import { Injectable } from '#angular/core';
import { Platform, Events } from '#ionic/angular';
import { HttpClient } from '#angular/common/http';
import { Storage } from '#ionic/storage';
import { BehaviorSubject } from 'rxjs';
import { tap } from 'rxjs/operators';
import { FirebaseX } from "#ionic-native/firebase-x/ngx";
import { environment } from '../../environments/environment';
import { AppService } from './app.service';
import { AuthService } from './auth.service';
#Injectable({
providedIn: 'root'
})
export class NotificationService {
fcm_token:any = null;
constructor(
private platform: Platform,
private http:HttpClient,
private appService:AppService,
private firebase: FirebaseX,
public events: Events,
public authService:AuthService,
) { }
async initialize(){
console.log('notificationService.initialize()');
let self = this;
let platforms = this.platform.platforms();
if(platforms.includes('ios') || platforms.includes('android')){
this.firebase.getToken().then(token => {
if(platforms.includes('ios')){ this.firebase.grantPermission(); }
if(platforms.includes('android')){ }
self.saveToken(token);
}).catch(error => console.error('FIREBASE Error getting token', error));
this.firebase.onTokenRefresh().subscribe((token: string) => { self.saveToken(token); });
this.firebase.onMessageReceived().subscribe(data => { });
}else{
// using browser, do nothing
}
}
async saveToken(token){
console.log('notificationService.saveToken()', token);
if(this.authService.is_logged == true){
this.fcm_token = token;
return this.http.post(environment.api_url+'/user/save-fcm-token', {fcm_token:this.fcm_token}, {headers:{'Authorization':'Bearer '+this.authService.auth_token}}).toPromise();
}
}
}
What else can I try?
Is there some place when I can see sending/receiving push errors?

Why Is User Automatically Logged out?

I have a simple app set up in Ionic 3 with a login page and a home page. I check to see if the user is logged in, then redirect to either the login page or the home page. That part seems to work.
After the login, on the home page I am trying to get the current logged in user. I get the user twice, and then it returns null twice. Why is the user not persistent? According the the AngularFire docs, the login should be persistent by default.
app.component.ts:
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage:any;
constructor(private afAuth: AngularFireAuth, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
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();
const authObserver = this.afAuth.authState.subscribe(user =>{
if (user){
this.rootPage = 'HomePage';
authObserver.unsubscribe();
} else {
this.rootPage = 'LoginPage'
authObserver.unsubscribe();
}
});
});
}
}
login.ts:
export class LoginPage {
user = {} as User;
constructor(public authData: AuthProvider, public navCtrl: NavController, public navParams: NavParams) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad LoginPage');
}
login(user: User){
this.authData.loginUser(user.email, user.password).then( authData => {
this.navCtrl.setRoot('HomePage');
}, error => {
console.log('Something went wrong')
});
}
}
home.ts:
export class HomePage {
constructor(private afAuth: AngularFireAuth, public authData: AuthProvider, public navCtrl: NavController, public navParams: NavParams) {
this.afAuth.auth.onAuthStateChanged(user => {
console.log(user);
});
}
}
logs:
login.ts:27 ionViewDidLoad LoginPage
home.ts:22 Hk {D: Array(0), G: "XIzaSyDn9pRx23NeEaCNVMQ0sBveDxYEsGrGvRA", s: "[DEFAULT]", A: "pigs-n-bulls-xxxxxxxx.firebaseapp.com", b: xh, …}
home.ts:22 Hk {D: Array(0), G: "XIzaSyDn9pRx23NeEaCNVMQ0sBveDxYEsGrGvRA", s: "[DEFAULT]", A: "pigs-n-bulls-xxxxxxxx.firebaseapp.com", b: xh, …}
home.ts:27 ionViewDidLoad HomePage
home.ts:22 null
home.ts:22 null
this.afAuth.auth.auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL);
or
this.afAuth.auth.auth.setPersistence(firebase.auth.Auth.Persistence.SESSION);
Then in your auth check code:
this.afAuth.auth.auth.onAuthStateChanged(user => {
if (!user) {
}
}
Take not I am using Angularfire, but accessing the Firebase auth functions directly.

Ionic Observable can't use data outside subscribe async/sync conflict

I am searching google all day for this problem. I understand why it is not working, but i can't find any solution or other way to get it work. I need to get it working.
I have made my own API that is correctly working when I surf to the url I get a JSON document with values. But now I got the problem with Ionic Asynchronous and Synchronous problems.
Api Service
import { Injectable } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class ApiService {
constructor(private _http: HttpClient) { }
public getUserById(id: string)
{
return this._http.get(`mysite`);
}
profile.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { ApiService} from '../../services/ApiService';
#IonicPage()
#Component({
selector: 'page-profile',
templateUrl: 'profile.html',
})
export class Profile{
user : any;
constructor(public navCtrl: NavController, public navParams: NavParams, private api : ApiService) {
}
ionViewDidLoad() {
this.api.getUserById('test').subscribe(data => {
this.user = data;
console.log(this.user);
});
console.log(this.user);
console.log('ionViewDidLoad ProfilePage');
}
}
you see two console.log(this.user), one inside the subscribe (this ons is working I see my JSON in the console). the second one outside the subscribe (this one gives a error undifined).
After searching on google I found this article that explains why it is not working. But I can't find any other solution on how to do it the correct way, because now I can't use {{user.name}} (for example) on my html.
My question is how should I work around this or how can you use API with Ionic.

FCMPlugin is not Defined in home.ts

I am trying to send a Push notification Using Firebase and Ionic 3. I have already imported the FCMPlugin in my project though my cmd. When I am creating a new message in firebase and try tos end, I don't receive anything, I run console log in my project and it gives me the following error "FCMPlugin is not defined".
I have declared the Plugin in my home.ts, but I am still getting this error, my home.ts is as follows:
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import {AlertController} from 'ionic-angular';
declare var FCMPlugin: any; // <---- this is the magic line
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(private alert:AlertController, private platform:Platform) {
this.onNotification();
}
async onNotification(){
try {
await this.platform.ready();
FCMPlugin.onNotification((data)=>{
this.alert.create({
message: data.message
}).present();
},(error) => console.error(error));
}
catch (e) {
console.error(e);
}
}
}
Can anyone provide me some guidance asIi am quite new to ionic?
Thanks in Regards
try using the FCM onNotification method inside an if block so that whenever you use it on a browser or whenever FCM is called before its initialisation it will not throw an error:
if (typeof FCMPlugin != 'undefined') {
FCMPlugin.onNotification((data)=>{})
}

how to determine if user is logged in "recently" in firebase

I'm trying to implement an angular guard to check if the user was signed in recently so they can change password, update email etc.
Using either angular fire 2 or angular I have a handle to the user (firebase.User). But how do I check if they qualify for "recently logged in" to perform sensitive operations?
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '#angular/router';
import { Observable } from 'rxjs/Rx';
import { Injectable, OnInit } from '#angular/core';
import { AuthService } from './auth.service';
import * as firebase from 'firebase/app';
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> {
return this.authService.user$.map((user) => {
if (user) {
// how to validate that this user is a recent login?
return true;
} else {
console.log('not authenticated');
this.router.navigateByUrl('/login');
return false;
}
}).first();
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.canActivate(route, state);
}
}
Why not just always re-authenticate before any sensitive information. It is common practice and Firebase provides APIs for re-authentication. You can check the auth_time in the Firebase ID token for the time of the last sign-in but Firebase Auth doesn't document the criteria for the recently logged in requirement and likely won't as they reserve the right to change it for security reasons. You are better off just requiring reauthentication, or you can try to updatePassword/updateEmail but if you get that specific error, reauthenticate and then try again.

Resources