I am a beginner in Ionic and I am developing an app which requires a user to sign in before he places an order.
Right now, if the user tries to place an order and he is not signed in, I need a logic where I can redirect him to the login page and on success, I can redirect him back to the order page. This would have been possible in android using start activity for the result. But how can I achieve this in Ionic?
I have a solution of opening the login page using modal and dismissing it on success but I do not want to implement that solution as of now.
Here is an example whcih open modal via login. Path and IonicPage should be adjusted before using the below code. Maybe you can get a point from the code.
home.ts
import { Component } from '#angular/core';
import { AuthProvider } from '../../providers/auth/auth.provider'
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public authService:AuthProvider) {
}
goToOrder(){
this.authService.openModalViaLogin('OrderPage', {}, ()=>{})
}
}
login.ts
import { Component } from '#angular/core';
import { IonicPage, ViewController } from 'ionic-angular';
import { AuthProvider } from '../../providers/auth/auth.provider';
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
constructor(public authService:AuthProvider, public viewCtrl:ViewController) {
}
login(){
this.authService.isAuthenticated = true;
this.viewCtrl.dismiss()
}
close(){
this.viewCtrl.dismiss()
}
}
auth.provider.ts
import { Injectable } from '#angular/core';
import { ModalController } from 'ionic-angular';
#Injectable()
export class AuthProvider {
public isAuthenticated:boolean = false;
constructor(public modalCtrl:ModalController) {
console.log('Hello AuthProvider Provider');
}
public openModalViaLogin(modalPage:string, params:any, callbackOnDidDismissed:Function){
if(this.isAuthenticated){
let modal = this.modalCtrl.create(modalPage,params)
modal.onDidDismiss(()=>{
callbackOnDidDismissed()
})
modal.present()
}else{
let loginModal = this.modalCtrl.create('LoginPage')
loginModal.onDidDismiss(()=>{
if(this.isAuthenticated){
let modal = this.modalCtrl.create(modalPage,params)
modal.onDidDismiss(()=>{
callbackOnDidDismissed()
})
modal.present()
}else{
console.log("failed to authenticate")
}
})
loginModal.present()
}
}
}
p.s. I think there is a more flexible way to achieve it by nav but that can be quite confusing with this short anwser.
Related
I have a problem testing my ionic app on my phone and android studio, when i press the hardware back button the application inmediatly exits, i've tried many solutions, but it simply won't work and won't listen to whatever i code into it.
Here is my attempt
import { Component, Renderer2, ViewChild } from '#angular/core';
import { IonRouterOutlet, Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { TranslateService } from '#ngx-translate/core';
import { Location } from '#angular/common';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
#ViewChild(IonRouterOutlet, {static: true}) routerOutlet: IonRouterOutlet
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private renderer: Renderer2,
private translate: TranslateService,
private location: Location
) {
this.initializeApp();
}
initializeApp() {
this.translate.setDefaultLang( localStorage.getItem('default-language') ? localStorage.getItem('default-language') : navigator.language.slice(0, 2) )
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
this.backButtonEvent();
if (localStorage.getItem('color-theme')) {
this.renderer.setAttribute(document.body, 'color-theme', localStorage.getItem('color-theme'))
} else {
if(window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches === true)
this.renderer.setAttribute(document.body, 'color-theme', 'light')
else
this.renderer.setAttribute(document.body, 'color-theme', 'dark')
}
});
}
backButtonEvent() {
this.platform.backButton.subscribeWithPriority(0, async () => {
if(!this.routerOutlet.canGoBack())
navigator["app"].exitApp()
else
this.location.back()
});
}
}
Try it this way using the #capacitor/app package:
import { App } from '#capacitor/app';
App.addListener('backButton', ({ canGoBack }) => {
if(canGoBack){
window.history.back();
} else {
App.exitApp();
}
});
I'm working on ionic 4 application. when the user signs In, I added a checkbox to asks for Remember me, so the next time the user open the app it doesn't show the login page and directly forward the user to Home page. I have google and found this. However, while using the accepted solution, I encountered an issue, which it shows the login page for 2 or 3 seconds, then open the Home page. How I can safely achieve it without delay?
app.component.ts
import { SmsVerificationService } from 'src/app/services/SMS/sms-verification.service';
import { Component } from '#angular/core';
import { Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { FCM } from '#ionic-native/fcm/ngx';
import { Plugins, Capacitor } from '#capacitor/core';
import { Router } from '#angular/router';
import { Storage } from '#ionic/storage';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private fcm: FCM,
private route: Router,
private storage: Storage
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.fcm.getToken().then(token => {
console.log(' token is ', token);
});
this.fcm.onTokenRefresh().subscribe(token => {
console.log('on token refresh ', token);
});
this.fcm.onNotification().subscribe(data => {
console.log(data);
if (data.wasTapped) {
console.log('Received in background');
// this.router.navigate([data.landing_page, data.price]);
} else {
console.log('Received in foreground');
// this.router.navigate([data.landing_page, data.price]);
}
});
this.storage.get('isLogined').then(data => {
if (data)
this.route.navigateByUrl('/main-tab');
})
this.statusBar.styleDefault();
this.splashScreen.hide();
if (Capacitor.isPluginAvailable('SplashScreen')) {
Plugins.SplashScreen.hide();
}
});
}
}
The codes that are supposed to change the page
this.storage.get('isLogined').then(data => {
if (data)
this.route.navigateByUrl('/main-tab');
})
Do you have a separate login component? If so, you can create and add a guard to your login component to navigate to your main page when Remember me was checked.
The problem is:
I want to establish communication between my desktop and my android smart device.
I'm trying a simple step but I get "device not found" as return
this is where I base my coding:
https://ionicframework.com/docs/native/serial/
this is the code:
import { Component, OnInit } from '#angular/core'; import {
NavController } from 'ionic-angular'; import {Serial} from
'#ionic-native/serial';
#Component({ selector: 'page-home', templateUrl: 'home.html' })
export class HomePage implements OnInit { public status:string;
constructor(public navCtrl: NavController, public serial:Serial) {
}
ngOnInit(){
this.serial.requestPermission({vid:"04e8",pid:"6860",driver:"FtdiSerialDriver"})//I
already have tried to omit the request options but got the same error
.then(()=>{
this.status = "Permission requested"; //this would be the successfully result }).catch(error=>{
this.status = error.toString(); // it's returning "device not found" }); } }
there are few content about this feature on web.
Good evening. I am trying to handle notification click in such a way that when the user click on a notification, a specific page of my application is opened.
I am using FIREBASE COULD MESSAGING AND IONIC 3
Here is the code of the app.component.ts file in witch the code for handling notification is written :
import { Platform, Nav, ToastController } from 'ionic-angular';
import { HomePage } from '../pages/home/home';
import { Component, ViewChild } from '#angular/core';
import { FCM } from '#ionic-native/fcm';
import { Signup } from '../pages/signup/signup';
#Component({
templateUrl: 'app.html',
selector: 'Myappname',
})
export class MyApp {
#ViewChild(Nav) nv: Nav;
rootPage: any = HomePage;
constructor(public fcm: FCM, platform: Platform) {
platform.ready().then(() => {
fcm.onNotification().subscribe(data => {
if (data.wasTapped) {
this.nv.push(Signup);
} else {
console.log("Received in foreground");
}
})
});
}
}
When the nofication is received on the mobile device, if the user click on it, only the home page is displayed and he is note redirected to the signup page as specified in the code.
Any helps ?
Thanks.
I finally found the solution. as i was using firebase cloud functions to send the notification, here is the code i used to make the onNotification() work when a user click on the notification received.
exports.Hello = functions.database.ref('/users/{userId}').onCreate(event=>{
admin.messaging().sendToTopic('all', {
data:{
"key1": value1,
"key2": value2
},
notification: {
clickAction : "FCM_PLUGIN_ACTIVITY",
sound : "default",
title : "Notification title",
body : "message content"
}
});
});
So We must set clickAction property of the notification object to FCM_PLUGIN_ACTIVITY to make onNotification() method execute when the user tapped on the notification.
Here is a code exemple for the app.component.ts in witch the onNotification() method is implemented.
import { Platform, Nav, ToastController } from 'ionic-angular';
import { HomePage } from '../pages/home/home';
import { Component, ViewChild } from '#angular/core';
import { FCM } from '#ionic-native/fcm';
import { Signup } from '../pages/signup/signup';
#Component({
templateUrl: 'app.html',
selector: 'Myappname',
})
export class MyApp {
#ViewChild(Nav) nv: Nav;
rootPage: any = HomePage;
constructor(public fcm: FCM, platform: Platform) {
platform.ready().then(() => {
fcm.onNotification().subscribe(data => {
if (data.wasTapped) {
this.nv.push(Signup);
} else {
console.log("Received in foreground");
}
})
});
}
}
AND now, it works fine !
Try setting the root page as the signup page, hopefully it will work:
this.nv.setRoot(Signup);
and if that doesnt work try adding this before your fcm.onNotification()
var $this = this;
and then use $this to reference inside your if statement // (wasTapped)
$this.nv.setRoot(Signup);
this is my code :
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { FileOpener } from 'ionic-native';
#Component({
selector: 'page-installHelper',
templateUrl: 'installHelper.html'
})
export class InstallHelper {
constructor(public navCtrl: NavController) {
FileOpener.open('assets/app.apk', 'application/vnd.android.package-archive').then(
function(){
console.log("success");
}, function(err){
console.log("status : "+err.status);
console.log("error : "+err.message);
});
}
}
but I can't access the file app.apk which is in assets/app.apk
and I get the error :
Status : 9
Error : File Not Found
is it even possible to access a file within the app folders ?
Well I did it by making the app get downloaded from a server to a local folder I created in the phone and install it immediately/automatically,
Here is the code in case someone else needed it one day :
import { Component } from '#angular/core';
import { Platform, LoadingController } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { FileOpener } from 'ionic-native';
import { File } from 'ionic-native';
import { Transfer } from 'ionic-native';
import { HomePage } from '../pages/home/home';
declare var cordova: any;
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage = HomePage;
constructor(platform: Platform, public loadingCtrl: LoadingController) {
let me = this;
platform.ready().then(() => {
let loading = me.loadingCtrl.create({
content: 'Preparing The App ...'
});
loading.present();
File.createDir(cordova.file.externalDataDirectory, "appFolder", true).then(function(link){
const fileTransfer = new Transfer();
let url = 'http://yourserverhere.com/app.apk';
fileTransfer.download(url, cordova.file.externalDataDirectory +"appFolder/app.apk").then((entry) => {
loading.dismiss();
FileOpener.open(entry.toURL(), "application/vnd.android.package-archive").then(
function(){
console.log("success");
},function(err){
console.log("status : "+err.status);
console.log("error : "+err.message);
});
}, (error) => {
console.log(error);
});
},function(error){
console.log(error);
});
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
Any explanation just ask me.
Well since you want the user to download the .apk file, you could use (in your html)
<a href="assets/app.apk" download>Download apk</a>
But the user will have to manually open his downloads (or tap the popup) to install your app.
I do not know if there is a plugin which is capable of installing these apk files. (Googling for ionic 2 install external apk didn't return any results).