A notification appears, but upon clicking them, they only open the application again. What I want is upon clicking the notification, it opens a specific item.
In Laravel, I am using the brozot/Laravel-FCM package for Firebase Cloud Messaging (FCM) to send notifications, and on the other end, I'm using Ionic push notifications to receive and display notifications in the notification tray.
If I don't use setClickAction() on Laravel, the Ionic application opens upon clicking the notification, but if I set setClickAction(), then nothing happens. The notification merely disappears.
Laravel-code:
$notificationBuilder = new PayloadNotificationBuilder('my title');
$notificationBuilder->setBody('Hello world')
->setSound('default')
->setClickAction('window.doSomething');
$notification = $notificationBuilder->build();
Ionic 2 framework sample:
import { Component, ViewChild } from '#angular/core';
import { Platform, Nav, MenuController, ModalController, Events, AlertController } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { Push, PushObject, PushOptions } from '#ionic-native/push';
import { Storage } from '#ionic/storage';
import {
SearchPage
} from '../pages/pages';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any = SearchPage;
constructor(
platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
private menu: MenuController,
private modalCtrl: ModalController,
private events: Events,
private push: Push,
private alertCtrl: AlertController,
private storage: Storage
) {
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();
});
this.pushSetup();
}
pushSetup() {
const options: PushOptions = {
android: {
senderID: 'xxxxxxxxxxx',
forceShow: true
},
ios: {
senderID: 'xxxxxxxxxxx',
alert: 'true',
badge: true,
sound: 'true'
},
windows: {},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
}
};
const pushObject: PushObject = this.push.init(options);
pushObject.on('notification').subscribe((notification: any) => {
});
pushObject.on('registration').subscribe((registration: any) => {
alert(registration.id);
});
pushObject.on('error').subscribe(error => alert('Error with Push plugin' + error));
}
}
(<any>window).doSomething = function () {
alert('doSomething called');
}
What am I missing?
There are these steps that need to be done for general One-Signal push notification to be implemented
Create a OneSignal Account
Add a New APP in the One Signal , configure for Android first (you can target for any platform but i'm focussing on Android as of now) .you need to get the Google Server Key and Google Project Id.
You can get the Above keys from the Firebase using this Steps
Now we are done with Configuring the OneSignal Account, now integrate with the ionic using the cordova plugin
In Ionic2 :
OneSignal.startInit(//google Server Key, //Google ProjectId);
OneSignal.inFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification);
OneSignal.setSubscription(true);
OneSignal.handleNotificationReceived().subscribe(() => {
// handle received here how you wish.
// this.goToReleatedPage(data.Key, data.Value);
});
OneSignal.handleNotificationOpened().subscribe((data: any) => {
//console.log('MyData'+ JSON.stringify(data.additionalData));
this.parseObject(data);
});
OneSignal.endInit();
ParsingObject in Ionic
public parseObject(obj) {
for (var key in obj) {
this.goToReleatedPage(key, obj[key]);
if (obj[key] instanceof Object) {
this.parseObject(obj[key]);
}
}
}
goToReleatedPage Method
public goToReleatedPage(Key, Value) {
//console.log("Pagename"+" " + Key + "ID" +" " + Value);
if (Key === 'xxxx') {
this.navCtrl.push(xxxPage, {
id: Value
});
} else if (Key === 'Foo') {
this.navCtrl.push(foosPage, {
id: Value,
});
} else if (Key === 'bar') {
this.navCtrl.push(barPage, {
id: Value
});
}
}
While sending the Message from OneSignal , you need to specify which page you need to open and you want to pass Id as follows
Related
I am currently using ionic capacitor PushNotifications for Firebase cloud messaging. By the help of this I can get tokens.
Now I want to send notifications to all app users so I decided to use topics.
For this, I installed community/FCM plugin.
capacitor-community/fcm
I also made suggested changes in the MainActivity.java file, no error during app build.
But after installation this FCM plugin, PushNotifications(token) stop working.
Even below code starts always retuning false.
if (isPushNotificationsAvailable) {
this.initPushNotifications();
}
Here is my MainActivity.java file:-
package io.ionic.starter;
import com.getcapacitor.community.fcm.FCMPlugin;
import android.os.Bundle;
import com.getcapacitor.BridgeActivity;
import com.getcapacitor.Plugin;
import java.util.ArrayList;
public class MainActivity extends BridgeActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initializes the Bridge
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
// Additional plugins you've installed go here
// Ex: add(TotallyAwesomePlugin.class);
add(FCMPlugin.class);
}});
}
}
Here my fcm.service.ts File:-
import { Component, Injectable } from '#angular/core';
import { Capacitor } from '#capacitor/core';
import { Router } from '#angular/router';
import { Storage } from '#ionic/storage';
import {
ActionPerformed,
PushNotificationSchema,
PushNotifications,
Token
} from '#capacitor/push-notifications';
// import { FCM } from '#capacitor-community/fcm';
const isPushNotificationsAvailable = Capacitor.isPluginAvailable('PushNotifications');
#Injectable({
providedIn: 'root'
})
export class FcmService {
public topicName = 'project';
constructor(
private router: Router,
private storage: Storage
) { }
initPush() {
//This Plugin is not available on web
if (isPushNotificationsAvailable) {
this.initPushNotifications();
}
}
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
private initPushNotifications() {
//console.log('Initializing HomePage');
PushNotifications.requestPermissions().then(result => {
if (result.receive === 'granted') {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
}
});
PushNotifications.addListener('registration', (token: Token) => {
alert('Push registration success, token: ' + token.value);
//Store Devive Token in session variable
this.storage.set("device_token", token.value);
// FCM.getToken()
// .then((r) => alert(`Token ${r.token}`))
// .catch((err) => console.log(err));
// now you can subscribe to a specific topic
// FCM.subscribeTo({ topic: this.topicName })
// .then((r) => alert(`subscribed to topic`))
// .catch((err) => console.log(err));
});
PushNotifications.addListener('registrationError', (error: any) => {
//alert('Error on registration: ' + JSON.stringify(error));
});
PushNotifications.addListener(
'pushNotificationReceived',
(notification: PushNotificationSchema) => {
//alert('Push received: ' + JSON.stringify(notification));
},
);
PushNotifications.addListener(
'pushNotificationActionPerformed',
(notification: ActionPerformed) => {
// alert('Push action performed: ' + JSON.stringify(notification));
const data = notification.notification.data;
//console.log('Action performed: ' + JSON.stringify(notification.notification));
if (data.detailsId) {
this.router.navigate(['/bid-project', data.detailsId]);
}
},
);
}
//Reset all Badge count
// resetBadgeCount() {
// PushNotifications.removeAllDeliveredNotifications();
// }
// move to fcm demo
// subscribeTo() {
// PushNotifications.register()
// .then((_) => {
// FCM.subscribeTo({ topic: this.topicName })
// .then((r) => alert(`subscribed to topic ${this.topicName}`))
// .catch((err) => console.log(err));
// })
// .catch((err) => alert(JSON.stringify(err)));
// }
// unsubscribeFrom() {
// FCM.unsubscribeFrom({ topic: this.topicName })
// .then((r) => alert(`unsubscribed from topic ${this.topicName}`))
// .catch((err) => console.log(err));
// }
}
After removing community plugin token generation started working as before.
Please tell me what wrong is with my code.
I have implemented the push notification functionality in my ionic app but it is not working. I am not getting the register id after the app is deployed. Following is my code.
app.component.ts
constructor(public platform: Platform, public splashScreen: SplashScreen, public menu: MenuController,
private storage: StorageService,private toast: ToastService, public events: Events, private push: Push,
private alertCtrl: AlertController, public network: Network, private api: UserService) {
platform.ready().then(() => {
debugger
this.pushSetup();
this.userDetails = this.storage.getData('userDetails');
this.isAlertShown = false;
// this.task = setInterval(() => {
// this.checkInternet();
// }, 3000);
if (this.userDetails != undefined || this.userDetails != null) {
this.rootPage = 'welcome';
} else {
this.rootPage = 'login';
}
this.initializeApp();
});
pushSetup() {
console.log("inside pushSetup");
const options: PushOptions = {
android: {
senderID: '592660866764',
forceShow: 'true'
},
ios: {
alert: 'true',
badge: true,
sound: 'false'
}
};
console.log("inside pushSetup 1");
const pushObject: PushObject = this.push.init(options);
pushObject.on('notification').subscribe((notification: any) => console.log('Received a notification', notification));
pushObject.on('registration').subscribe((registration: any) =>console.log('Received a notification', registration));
pushObject.on('error').subscribe(error => console.error('Error with Push plugin', error));
}
Install the Cordova and Ionic Native plugins:
ionic cordova plugin add onesignal-cordova-plugin
npm install --save #ionic-native/onesignal
insert in app.module.ts Onesignal
import { OneSignal } from '#ionic-native/onesignal';
providers: [
....
OneSignal
...
]
In App Component you needs One Signal App ID and Google Project ID
in app.component.ts:
import { OneSignal } from '#ionic-native/onesignal';
import { Platform } from 'ionic-angular';
constructor(public oneSignal: OneSignal,
private platform: Platform) { }
onseSignalAppId: string = 'YOUR_ONESIGNAL_APP_ID';
googleProjectId: string = 'YOUR_GOOGLE_PROJECT_ID';
if(this.platform.is('cordova')) {
if (this.platform.is('android')) {
this.oneSignal.startInit(this.onseSignalAppId, this.googleProjectId);
}
else if (this.platform.is('ios')) {
this.oneSignal.startInit(this.onseSignalAppId);
}
this.oneSignal.inFocusDisplaying(this.oneSignal.OSInFocusDisplayOption.Notification);
this.oneSignal.handleNotificationReceived().subscribe(() => {
// do something when notification is received
});
this.oneSignal.handleNotificationOpened().subscribe(result => {
// do something when a notification is opened
});
this.oneSignal.endInit();
// AND THIS METHOD RETURN YOUR DEVICES USER_ID
this.oneSignal.getIds().then(identity => {
alert(identity.pushToken + ' it's PUSHTOKEN');
alert(identity.userId + 'it's USERID);
});
}
i wrapped a website and there are external links which i made to open in System browser, but when I return to in-app browser using hardware back button and again try to open the external links it doesn’t open. It looks like the 'loadstart" occurs only once.Or am i doing anything wrong here?
home.ts
export class HomePage {
constructor(public navCtrl: NavController, private iab: InAppBrowser, public
platform: Platform,private fileOpener: FileOpener, private
transfer:FileTransfer, private file: File, private diagnostic:Diagnostic) {
platform.ready().then(() => {
const browser =
this.iab.create('https://www.tutorialspoint.com/ionic/index.htm','_blank',
{zoom:'yes',location:'no', clearcache: 'yes', clearsessioncache: 'yes'});
browser.show();
browser.on('loadstart').subscribe(
(data) => {
console.log("URL IS", data.url);
this.downloadfile(data.url)
},
err => {
console.log("InAppBrowser Loadstop Event Error: " + err);
}
);
});
}
downloadfile(url) {
var externalCheck = (!url.includes("tutorial.points"));
var pdfCheck = (url.substr(url.length - 4) == '.pdf');
if (externalCheck || pdfCheck) {
window.open(url, "_system", 'location=no');
}
}
}
Is there any solution for this ? any help is really appreciated.Thanks in advance
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">
at the moment iam implementing a signIn into my ionic 2 app.
I want to use ionic 2 native facebook and somehow save the data to my firebase app.
Is there any way to archive that?
One way is to create a new firebase auth user with the facebook email adress and some password hash, but maybe there is a better solution.
Here is what i got so far (i know, not much) :)
import {NavController, Loading, Platform, Storage, LocalStorage} from "ionic-angular";
import {OnInit, Inject, Component} from "#angular/core";
import {ForgotPasswordPage} from "../forgot-password/forgot-password";
import {SignUpPage} from "../sign-up/sign-up";
import {HomePage} from "../../home/home";
import * as firebase from 'firebase';
import {Facebook} from 'ionic-native';
/*
Generated class for the LoginPage page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
templateUrl: 'build/pages/auth/login/login.html',
})
export class LoginPage {
private local: any;
constructor(private navCtrl: NavController, private platform:Platform) {
this.local = new Storage(LocalStorage);
}
openForgotPasswordPage():void {
this.navCtrl.push(ForgotPasswordPage);
}
openSignUpPage():void {
this.navCtrl.push(SignUpPage);
}
login() {
firebase.auth().signInWithEmailAndPassword("test#test.com", "correcthorsebatterystaple").then(function (result) {
console.log("AUTH OK "+ result);
}, function (error) {
console.log("dawdaw");
});
}
facebookLogin() {
Facebook.login(['public_profile', 'user_birthday']).then(() => {
this.local.set('logged', true);
this.navCtrl.setRoot(HomePage);
}, (...args) => {
console.log(args);
})
} }
facebookLogin() {
Facebook.login(['public_profile', 'user_birthday']).then((result) => {
var creds = firebase.auth.FacebookAuthProvider.credential(result.access_token);
return firebase.auth().signInWithCredential(creds);
})
.then((_user) => {
console.log("_user:", _user);
})
.catch((_error) => {
console.error("Error:", _error);
});
}
see more info here - https://firebase.google.com/docs/auth/web/facebook-login#advanced-handle-the-sign-in-flow-manually
I have not tried this, so might not be 100% working, but try this Gist I found: https://gist.github.com/katowulf/de9ef6b04552091864fb807092764224