Push notifications with Ionic2

Hi All!

I decided to play a bit with ionic2 push notifications and started from this document: http://ionicframework.com/docs/v2/platform/push-notifications/.
Following the “Push Notification docs” the problems started right the beginning: ionic add ionic-platform-web-client results in:

ERROR: Error: ENOENT, open ‘C:\ionic2app\www\js\app.js’
at Error (native)
Is your app declaration contained in ‘app.js’?

Apparently the ionic cli is still aiming a v1 ionic app, so there won’t be any app.js inside /www/js. Even if I fake the file in there, it won’t be able to inject the code since app.js has a different format in v2. Any solution to this?

Furthermore it adds the following code to index.html:

<script src="lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js"></script>

which, of course, won’t work. When I ionic serve my app I get a beautiful 404 on the file.

Is there a manual solution to have the push notifications working in a v2 app?

Thank you for the help :grinning:

2 Likes

You can include the ionic bundle by editing the webpack configuration.

module.exports = {
  entry: [
      "ionic.io.bundle",
      ....

resolve: {
   modulesDirectories: [
    "lib/ionic-platform-web-client/dist",
....

// in your receiving component/page/service
// i seemed to need the Zone to hook into the Angular world, not sure if this is still needed in the latest version
this.zone = new NgZone({enableLongStackTrace: false});

Ionic.io();

this.push = new Ionic.Push({
  onNotification: (data) => {
    this.popup.alert({title: 'You have a notification'});
    
    this.zone.run(() => {
                     // do something here
    });
  }
});

Hey, thanks for the help :smiley: This is what I ended up doing: I added this line to the webpack.config.js file:

module.exports = {
  entry: [
    path.resolve('bower_components/ionic-platform-web-client/dist/ionic.io.bundle'),
    ......

By doing this I didn’t need to reference the .js in index.html since it is already being packed in the app.bundle.js. But I did comment out in index.html where the cordova.js is included, since it says cordova is bootstrapped in ionic-platform-web-client. So far so good, ionic.io.bundle is being imported, I then ran the ionic io init and tried to serve the app. Blank screen. Console says Uncaught TypeError: Cannot read property 'get' of undefined (app.bundle.js:4493). By looking at the source code it is clearly related to the ionic.io.bundle. I found people with the same issue here https://github.com/driftyco/ionic-platform-web-client/issues/4 and here https://github.com/driftyco/ionic-platform-web-client/issues/10, but unfortunately their solution won’t work. I tried editing ionic.io,bundle to add the code

“IONIC_SETTINGS_STRING_START”;
var settings = {
“dev_push”: true
};
return {
get: function(setting) {
if (settings[setting]) {
return settings[setting];
}
return null;
}
};
“IONIC_SETTINGS_STRING_END”;

But now I get a new error Uncaught TypeError: _settings.Settings is not a function (app.bundle.js:4762) This is the line where I get the error: var settings = new _settings.Settings();, in context:

var _settings = require(“./settings”);

var settings = new _settings.Settings();

Any idea where should I go from here? this ./settings is not being imported correctly, how do I find it?

Thank you :slight_smile:

I have this in my core/settings.js

var temp = new BaseSettings().factory('$ionicCoreSettings', function() {
  "IONIC_SETTINGS_STRING_START";
  "IONIC_SETTINGS_STRING_END";
  var settings = {
      "app_id": "foo",   
     "api_key": "bar",
     "gcm_key": "faz",
      "dev_push": false
  };
  return {
     "get": function(setting) {
           if (settings[setting]) {
              return settings[setting];
             }
           return null;
          }
  };
})

and then lower:

 get(name) {
    return temp.get(name);
   }

For me the gulp task works to rebuild this.

Thanks again for the help, I finally managed to get it (almost) working :sweat_smile: When I get it done I’ll write here the step-by-step.

The current problem: ionic.io.bundle is being successfully included and bootstrapped, but when I tried the sample code you gave before (plus the code to get the device id):

this.zone = new NgZone({enableLongStackTrace: false});

Ionic.io();

this.push = new Ionic.Push({
  debug: true,
  onNotification: (data) => {
    this.popup.alert({title: 'You have a notification'});
    this.zone.run(() => {
     // do something here
    });
  }
});

this.push.register(function(token) {
    console.log("Device token:",token.token);
});

Surprise: the push.register callback was not being executed. I then traced back why and found out that the Push.init() was never being called from the constructor (push/push.js). This bit from the Push constructor was not being executed:

  IonicPlatform.getMain().onReady(function() {
    self.init(config);
  });

I can’t understand why, but if put the self.init(config) outside the IonicPlatform.getMain().inRead() it just works perfectly. Apparently IonicPlatform.getMain() never gets ready. Any ideas?

Thanks!

I managed a workaround by simple calling init() after initializing the class (also the config is passed into init and not the constructor):

this.push = new Ionic.Push().init({
  debug: true,
  onNotification: (data) => {
    console.log('Push notification received');
  }
});

No idea what are the implications of this, but testing with ionic serve it works as expected. Haven’t tried on the device yet.

Here is the step-by-step to get the ionic.io push notifications working (currently alpha.46).

$ ionic add ionic-platform-web-client
$ ionic plugin add phonegap-plugin-push
$ ionic io init
$ ionic config set dev_push true

in webpack.config.js I addded the following line:

module.exports = {
  entry: [
    path.resolve('bower_components/ionic-platform-web-client/dist/ionic.io.bundle'),
    ......

in bower_components/ionic-platform-web-client/dist/ionic.io.bundle.js replace:

  "IONIC_SETTINGS_STRING_START";"IONIC_SETTINGS_STRING_END";

with

  "IONIC_SETTINGS_STRING_START";
    var settings = {
            "app_id": "YOUR APP_ID",
            "api_key": "YOUR APP_KEY",
            "gcm_key": "YOUR GCM_KEY",
            "dev_push": true
        };
        
    return {
        get: function(setting) {
            if (settings[setting]) {
                return settings[setting];
            }
            return null;
        }
    };
  "IONIC_SETTINGS_STRING_END";

Lastly, in your index.html you can remove <script src="lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js"></script> but leave <script src="cordova.js"></script> commented out.

Everything should work now. To initiate the push service, use:

    Ionic.io();
    ionicPush = new Ionic.Push().init({
        debug: true,
        onNotification: (data) => {
            console.log('New push notification received');
            console.log(data);
        }
    });

    ionicPush.register(data => {
        console.log("Device token:", data.token);
    });

Hope this helps someone in the same situation :slight_smile:

7 Likes

i’m using
Cordova CLI: 5.4.0
Ionic Version: 2.0.0-alpha.54
Ionic CLI Version: 2.0.0-beta.17
Ionic App Lib Version: 2.0.0-beta.8

and is not working i guess.
i followed step-by-step but the return still like that
{“app_id”:“864xxe16”,“errors”:[],“ios”:{“success”:false,“failure_reason”:"",“sent”:0},“android”:{“success”:false,“failure_reason”:"",“sent”:0},“status”:“Queued”}

and return a lot of errors when i set dev_push to false :frowning:

Does help. Thanks for the detailed instructions

Ionic.io() and methods works . But page not loading. And in terminal warning appears:

WARNING in ./~/ionic-platform-web-client/dist/ionic.io.bundle.js
Critical dependencies:
1:113-120 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/ionic-platform-web-client/dist/ionic.io.bundle.js 1:113-120

how to solve this problem ? :pensive:

I solved by changing path.resolve('node_modules/ionic-platform-web-client/dist/ionic.io.bundle') position from bottom to the top.

entry: [
    path.resolve('node_modules/ionic-platform-web-client/dist/ionic.io.bundle'),
    path.normalize('es6-shim/es6-shim.min'),
    'reflect-metadata',
    'web-animations.min',
    path.normalize('zone.js/dist/zone-microtask'),
    path.resolve('app/app'),
  ],

Could you solve this problem ? On production mode not working for me too.

Apparently there are several bugs and unexpected behaviour from Ionic Push. Try using http://ionicframework.com/docs/v2/native/Push/

I have just the same problem, while trying
$ ionic add ionic-platform-web-client in Ionic 2 project.
But maybe there is a more friendly workaround to fix it?
I’m afraid that making all these changing may interfere with future releases and will cause project to break in the future…

Thanks a lot… Worked perfectly… Really appreciate it…

i have implemented push in ioni2 app and have all the steps documented here without any chages in configs of ionic templates.
Push notifications in ionic2

Check if it helps.

Thanks a lot, this helped me on the way to getting Ionic Push working in an app based on ionic-angular 2.0.0-beta.7.

Because this version doesn’t use webpack I instead included the modified ionic.io.bundle.min.js file in www/index.html, on the line just after the inclusion of cordova.js.

Additionally I had to wrap the initialization code in the main class constructor inside an NgZone.runOutsideAngular block like the following:

this.zone.runOutsideAngular(() => {
	Ionic.io();

	let ionicPush = new Ionic.Push().init({
		debug: true,
		onNotification: (data) => {
			this.zone.run(() => {
				this.onPush(data);
			})
		}
	});

	ionicPush.register(data => {
		console.log("Device token:", data.token);
	});
});

Why would you want to use a Zone for that? See my Post for a fix:

The solution by fefelegal that I used is based on the Ionic Platform’s Push service which uses the ionic-platform-web-client tool for set-up and that is made for Ionic 1 projects. Do you mean that the Ionic 2 Push service (from ionic-native) can be used with the Ionic Platform’s Push service and in that case, how can it be set up?

hi @fefelegal,

the link you have given is not working any more.

here is what we saw there.

Ooops. The page you’re looking for got lost in space.

1 Like