Ionic 3 OneSignal Push Notification Click Open Page - ionic-framework

I use OneSignal Push Notification for Ionic 3 . I want to when click notification application open page.
My app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Platform, NavController } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { OneSignal } from '#ionic-native/onesignal';
import { DuyurularPage } from '../pages/duyurular/duyurular';
#Component({
templateUrl: 'app.html',
providers:[OneSignal],
template: '<ion-nav #myNav [root]="rootPage"></ion-nav>'
})
export class MyApp {
rootPage:any = 'MenuPage';
bgColor: string = '#fff';
#ViewChild('myNav') nav: NavController;
constructor(platform: Platform, statusBar: StatusBar, splashScreen:
SplashScreen, private oneSignal: OneSignal,) {
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
window["plugins"].OneSignal
.startInit("**************", "***********")
.handleNotificationOpened()
.handleNotificationReceived()
.endInit();
});
this.oneSignal.handleNotificationOpened().subscribe((jsonData) => {
alert(JSON.stringify(jsonData));
this.nav.push(DuyurularPage);
});
this.oneSignal.handleNotificationReceived().subscribe((jsonData) =>
{
alert(JSON.stringify(jsonData));
this.nav.push(DuyurularPage);
});
}
}
When I do mistake I don' t know. Notification coming but not show alert or not push DuyurularPage, just open homepage.

if you Need to Open a Specific page on Notification Tapped. Follow the technique.
In App.component.ts
this.oneSignal.handleNotificationOpened().subscribe((data) => {
// do something when a notification is opened
console.log('Tapped',data);
if(data.notification.payload.additionalData.landing_page != undefined && data.notification.payload.additionalData.landing_page != ''){
this.PushProvider.landing_page = data.notification.payload.additionalData.landing_page;
}
if(data.notification.payload.additionalData.product_id != undefined && data.notification.payload.additionalData.product_id != ''){
this.PushProvider.product_id = data.notification.payload.additionalData.product_id;
}
});
this.oneSignal.endInit();
//On Home Page
if(this.PushProvider.landing_page != undefined){
console.log('on home if',this.PushProvider.landing_page);
this.navCtrl.push('offerzonePage',{ from_tab: this.PushProvider.landing_page});
}
if(this.PushProvider.product_id != undefined){
console.log('on home if',this.PushProvider.product_id);
this.navCtrl.push('ProductPage',{ product_id: this.PushProvider.product_id });
}
On Pushprovicer.ts
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class PushProvider {
// Produc ID
product_id: any;
// Landing pages
landing_page: any;
}

can you use the below syntax and try;
import { Component, ViewChild } from '#angular/core';
import { Platform, NavController } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { OneSignal } from '#ionic-native/onesignal';
import { DuyurularPage } from '../pages/duyurular/duyurular';
#Component({
templateUrl: 'app.html',
providers:[OneSignal],
template: '<ion-nav #myNav [root]="rootPage"></ion-nav>'
})
export class MyApp {
rootPage:any = 'MenuPage';
bgColor: string = '#fff';
#ViewChild('myNav') nav: NavController;
constructor(platform: Platform, statusBar: StatusBar, splashScreen:
SplashScreen, private oneSignal: OneSignal,) {
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
this.oneSignal.startInit('*****', '***');
this.oneSignal.inFocusDisplaying(this.oneSignal.OSInFocusDisplayOption.InAppAlert);
this.oneSignal.handleNotificationOpened().subscribe((jsonData) => {
alert(JSON.stringify(jsonData));
this.nav.push(DuyurularPage);
});
this.oneSignal.handleNotificationReceived().subscribe((jsonData) =>
{
alert(JSON.stringify(jsonData));
});
}
You cannot use NavController in app.component.ts it seems.
Can you use Nav or App

What I would do is create an obsevable and subscribe to it anywhere needed in my app. The observable will emit its next value whenever the plugin callback is fired.
RxJS Observable
Emit next value on callback
Subscribe anywhere in your app
Use provided NavCtrl to push a component into the view
The same principle would work if you inject ionic's Event.
Btw you have a random comma at the end of your constructor

Related

passing parameter between pages ionic

Hi i´m new in ionic and I am trying to pass the scann information form one page to another, the thing its that when I execute the program I have a console.log to check if the info its passed correctly but on chrome console said undefined, letme paste my code:
home.ts where i try to send the info from the scan:
import { Component } from '#angular/core';
import { NavController,Platform } from 'ionic-angular';
import { BarcodeScanner } from '#ionic-native/barcode-scanner';
import { TabsPage } from '../tabs/tabs';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private barcodeText:String;
private barcodeFormat:String;
private platform:Platform;
private navController:NavController;
constructor(private barcodeScanner: BarcodeScanner,public navCtrl: NavController,platform:Platform) {
this.platform = platform;
this.navController = navCtrl;
}
doScan(){
console.log('scannig product barcode');
this.platform.ready().then(() => {
this.barcodeScanner.scan().then((result) => {
if (!result.cancelled) {
this.barcodeText = result.text;
this.scanningDone(this.barcodeText)
}
}, (error) => {
console.log('error when scanning product barcode');
});
});
}
scanningDone(data){
this.navController.push(TabsPage,{
data:data
});
}
main.ts where the info suppose to go:
import { Component } from '#angular/core';
import { NavController, NavParams , ToastController} from 'ionic-angular';
import { BarcodeScanner } from '#ionic-native/barcode-scanner';
import { DetailsPage } from '../details/details';
import { Http } from '#angular/http'
#Component({
selector: 'main',
templateUrl: 'main.html'
})
export class MainPage {
information: any[];
item:any;
private bcData;
constructor(public navCtrl: NavController, private http: Http,public params:NavParams) {
this.bcData = params.get('data');
console.log(params.get('data'));
let localData = http.get(this.bcData).map(res => res.json().items);
localData.subscribe(data => {
this.information = data;
})
}
on the console.log(params.get('data')); its where I get the undefinied on the console.
you could have a method in your TabsPage that handles opening and closing pages like this:
openPages(Page, Data){
this.navCtrl.push(Page,Data);
}
Then in your scanningDone Method:
scanningDone(data){
this.tabsPage.openPages(MainPage,{
data:data
});
}
How about using localStorage
look at this as well

Ionic 2: Facebook Login -> Error: No Provider in NavController (TypeScript)

I've been working on the facebook login for my ionic 2 app
(used this tutorial: https://ionicthemes.com/tutorials/about/ionic2-facebook-login)
But now i get a weird error:
RunTimeError Error in :0:0 caused by: No provider for NavController
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 { NativeStorage } from '#ionic-native/native-storage';
import { TabsPage } from '../pages/tabs/tabs';
import { WelcomePage } from '../pages/welcome/welcome';
import { DetailPage } from '../pages/detail/detail';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any = WelcomePage;
constructor(NativeStorage: NativeStorage, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Here we will check if the user is already logged in
// because we don't want to ask users to log in each time they open the app
let env = this;
NativeStorage.getItem('user')
.then((data) => {
// user is previously logged and we have his data
// we will let him access the app
this.rootPage = DetailPage;
splashScreen.hide();
}, (error) => {
//we don't have the user data so we will ask him to log in
this.rootPage = WelcomePage;
splashScreen.hide();
});
statusBar.styleDefault();
});
}
}
welcome.ts:
import { Component } from '#angular/core';
import { Facebook, NativeStorage } from 'ionic-native';
import { NavController } from 'ionic-angular';
import { DetailPage } from '../detail/detail';
import { ViewChild } from '#angular/core';
#Component({
selector: 'page-welcome',
templateUrl: 'welcome.html'
})
export class WelcomePage {
rootPage: any = WelcomePage;
#ViewChild('navRoot') navCtrl: NavController;
FB_APP_ID: number = 123456789;
constructor() {
Facebook.browserInit(this.FB_APP_ID, "v2.8");
}
doFbLogin() {
let permissions = new Array();
let nav = this.navCtrl;
//the permissions your facebook app needs from the user
permissions = ["public_profile"];
Facebook.login(permissions)
.then(function (response) {
let userId = response.authResponse.userID;
let params = new Array();
//Getting name and gender properties
Facebook.api("/me?fields=name,gender", params)
.then(function (user) {
user.picture = "https://graph.facebook.com/" + userId + "/picture?type=large";
//now we have the users info, let's save it in the NativeStorage
NativeStorage.setItem('user',
{
name: user.name,
gender: user.gender,
picture: user.picture
})
.then(function () {
nav.push(DetailPage);
}, function (error) {
console.log(error);
})
})
}, function (error) {
console.log(error);
});
}
}
You cannot import NavController in app.component.ts or the root app page.
OPTION 1:
Try to get it using ViewChild
Give element id to root-nav
<ion-nav #navRoot [root]="rootPage"></ion-nav>
In component:
import {ViewChild} from '#angular/core';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any = WelcomePage;
#ViewChild('navRoot') navCtrl:NavController;
constructor(nativeStorage: NativeStorage, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { //remove navcontroller injected
platform.ready().then(() => {
// Here we will check if the user is already logged in
// because we don't want to ask users to log in each time they open the app
let env = this;
//...
OPTION 2:
From your app.component.ts code, you dont actually need to import NavController at all if your html template only contains,
<ion-nav [root]="rootPage"></ion-nav>
Simply set the required page to rootPage.
nativeStorage.getItem('user')
.then( (data) => {
// user is previously logged and we have his data
// we will let him access the app
this.rootPage = DetailPage;
splashScreen.hide();
}, (error) => {
//we don't have the user data so we will ask him to log in
this.rootPage = WelcomePage;
splashScreen.hide();
});
Side Note: Better to use ()=>{} arrow functions for callbacks instead of saving context in second variable.

Pause MyApp during modal.present()

Original Post:
I am coding an Ionic 2 Hybrid app and attempting to create a modal that logs into FB and gathers necessary information for the app to run properly.
While the modal is presented (and the user is logging in), I need the app to be paused in the background. In other words, it cannot be continuing with the subsequent processes until the modal is dismissed.
Here is the relevant portion of code as an example:
var user = firebase.auth().currentUser;
if (user) {
console.log("User is already signed in.");
} else {
console.log("No user is signed in.");
let profileModal = this.modalCtrl.create(ProfilePage);
profileModal.present();
}
console.log("test pause.")
While the modal is still being presented and before it is dismissed, "test pause." is being written to the console. I need it to NOT be written to the console until AFTER the modal is dismissed.
NOTE: I have everything working properly except this bit. I haven't figured out how to accomplish 'pausing' until the modal is dismissed.
Is there any way to do this?
Clarification:
I am presenting the modal in the ngOnInit() of the main app component. I am doing this because I need specific user information to be gathered before the main app component is loaded and any pages are set/added to the stack.
Otherwise, the rootpage will not be built properly.
Here is the updated code in its full context in the app.component.ts file:
import { Component, ViewChild, OnInit } from '#angular/core';
import { ModalController, Nav, Platform } from 'ionic-angular';
import { SettingsService } from './../services/settings';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HomePage } from './../pages/home/home';
import { SignInPage } from './../pages/signin/signin';
import { CreatePage } from './../pages/create/create';
import { ProfilePage } from './../modals/profile/profile';
import firebase from 'firebase';
#Component({
templateUrl: 'app.html'
})
export class MyApp implements OnInit {
#ViewChild(Nav) nav: Nav;
rootPage: any = HomePage;
homePage: any = HomePage;
signInPage: any = SignInPage;
createPage: any = CreatePage;
photoURL: string;
constructor(private modalCtrl: ModalController,
private platform: Platform,
private statusBar: StatusBar,
private splashScreen: SplashScreen,
private settingsService: SettingsService) {
this.initializeApp();
}
ngOnInit() {
var config = {
apiKey: "AIzaSyDmTh_LZuMPnn7nJRquoW5xWwgQ4Ia3J9E",
authDomain: "thevault-ba308.firebaseapp.com",
databaseURL: "https://thevault-ba308.firebaseio.com",
projectId: "thevault-ba308",
storageBucket: "thevault-ba308.appspot.com",
messagingSenderId: "1024205108979"
};
firebase.initializeApp(config);
var user = firebase.auth().currentUser;
if (user) {
console.log("User is already signed in.");
}
else {
console.log("No user is signed in.");
let profileModal = this.modalCtrl.create(ProfilePage);
profileModal.present();
profileModal.onDidDismiss(() => {
console.log("test pause.")
this.photoURL = this.settingsService.getUserPhoto();
console.log(this.settingsService.getUserName());
})
}
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page) {
this.nav.setRoot(page);
}
signOut() {
firebase.auth().signOut().then((result) => {
console.log("Sign out success.");
this.nav.setRoot(SignInPage);
}).catch((error) => {
console.log(error.message);
});
}
}
You should move all the code that was supposed to execute after modal is dismissed in this modal.onDismiss() part. Like this:
let profileModal = this.modalCtrl.create(ProfilePage);
profileModal.present();
profileModal.onDismiss((data) => {
console.log("Data from modalPage :",data);
console.log("test pause."); // Here you go. The code will be paused till the modal is dismissed.
});
Moreover, you can pass data to the modalPage via navParams and retrieve from the modalPage as well using this.viewCtrl.dismiss(data);.
For more reference, look at this and this ionic 2 documentation.
I was able to resolve my problem by using *ngIf in the app.html file.
<ion-content *ngIf="photoURL != null">

ionic 2 check if user already logged in with angularfire2

I did facebook login to my app and I'm trying to check if the user logged in then go to HomePage,if not go to loginPage.
I did it with firebase but I'm trying to do that with angularfire2
that's my code with firebase (I want it in angularfire2)
firebase.auth().onAuthStateChanged((user) => {
var that=this;
if (user) {
if(this.reg_boolean=="true"){
console.log("regCompleted");
this.nav.setRoot(TabsPage,{
dep:this.department,year:this.year,semester:this.semester
})
this.rootPage=TabsPage;
}
else{
this.rootPage = SignupPage;
}
console.log("I'm here! HomePage");
} else {
this.rootPage = LoginPage;
console.log("I'm here! LoginPage");
}
});
I got this to work in app.component.ts file.
import { ViewChild } from '#angular/core';
import { Nav } from 'ionic-angular';
import { AngularFire } from 'angularfire2'; // import this, duh
import { HomePage } from '../pages/home/home';
import { LoginPage } from '../pages/login/login';
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any;
pages: Array<{ title: string, component: any }>;
userName:string;
constructor(public platform: Platform,
public af: AngularFire,
public authService: AuthenticationService) { // used for logout
this.initializeApp();
// Listen for auth sub
af.auth.subscribe(user => {
this.rootPage = user ? HomePage : LoginPage;
});
....
So basically get listening on the subscribe and change the rootPage based on the value passed into the var user. You can do a console.log() on user if you want to be more specific with the redirection.

Assigning an import to a variable within a constructor

I am building an app in Ionic2. I want to implement Facebook within the app and so I am trying to use the ionic-native Facebook api. I imported it and then attempted to assign it to a variable so I could use the functions associated with it.
Here is my code.
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Facebook } from 'ionic-native';
#Component({
selector: 'page-news-feed',
templateUrl: 'news-feed.html',
})
export class NewsFeed {
fb: any;
constructor(public navCtrl: NavController, facebook: Facebook) {
this.fb = facebook;
}
doRefresh(refresher) {
console.log('Begin async operation', refresher);
setTimeout(() => {
console.log('Async operation has ended');
refresher.complete();
}, 2000);
}
this.fb.login([]);
ionViewDidLoad() {
console.log('Hello NewsFeed Page');
}
}
I thought an import works much like a class in that you can import it and assign it to a variable and then have access to its methods. Does it not work like that? How does it work?
You just have to import Facebook class like it is said in Ionic native docs :
https://ionicframework.com/docs/v2/native/
You don't need to inject it through the constructor. As method are static this will print an error.
Be sure to also call Facebook after platform.ready event. And don't forget to add the plugin. See your example modified accordingly.
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Facebook } from 'ionic-native';
#Component({
selector: 'page-news-feed',
templateUrl: 'news-feed.html',
})
export class NewsFeed {
constructor(public navCtrl: NavController, platform: Platform) {
platform.ready().then(() => {
console.log('Faceboook');
Facebook.login([]).then((response) => {
console.log(response);
}).catch((error) => {
console.error(error);
});
})
}
doRefresh(refresher) {
console.log('Begin async operation', refresher);
setTimeout(() => {
console.log('Async operation has ended');
refresher.complete();
}, 2000);
}
ionViewDidLoad() {
console.log('Hello NewsFeed Page');
}
}