Integrating OneSignal with Angular

PsyGik picture PsyGik · Jul 27, 2017 · Viewed 10.7k times · Source

I'm trying to integrate OneSignal into my Angular 2 app to receive push notifications. First I did a HelloWorld app using plain old HTML and it works beautifully. So I tried to include it into my Angular app, but users are not getting created/registered, and hence are not subscribed to receive any notifications.

Code excerpts:

index.html

<html>

<head>
  <meta charset="utf-8">
  <title>My Angular App</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <head>
    <link rel="manifest" href="/manifest.json">
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async></script>
  <script>
    var OneSignal = window.OneSignal || [];
    console.log("Init OneSignal");
    OneSignal.push(["init", {
      appId: "xxx-xxx-xxx-xxx-xxx",
      autoRegister: false,
      allowLocalhostAsSecureOrigin: true,
      notifyButton: {
        enable: true
      }
    }]);
    console.log('OneSignal Initialized');
    OneSignal.push(function () {
      console.log('Registered For Push');
      OneSignal.getUserId().then(function (userId) {
      console.log("User ID is", userId);
      });
    });
  </script>
  </head>
</head>

<body>
  <app-root>
    <div class="wrap">
      <div class="loading outer">
        <div class="loading inner"></div>
      </div>
    </div>
  </app-root>
</body>

</html>

The userId is always null.

I've checked the following:

  • App ID is correct
  • Permission for Notification is set to allow in the browser

Questions:

  • Is there a way to do all the init stuffs inside any component, say in the ngOnInit() method?
  • I would like to register for push when user clicks on a button inside my component rather than using the bell icon? How does one achieve that? ( I know that setting notifyButton to false will not show the notify bell)

P.S: Testing on Chrome using Angular CLI (Didn't work with FF or Safari)

Answer

PsyGik picture PsyGik · Jul 27, 2017

I'm afraid I presented another case of skimming the docs instead of actually reading it.

So I moved the code around a bit and this is what ended up working for me.

index.html

<html>

<head>
  <meta charset="utf-8">
  <title>My Angular App</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <head>
    <link rel="manifest" href="/manifest.json">
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async='async'></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
  </head>
</head>

<body>
  <app-root>
    <div class="wrap">
      <div class="loading outer">
        <div class="loading inner"></div>
      </div>
    </div>
  </app-root>
</body>

</html>

app.component.ts

export class AppComponent implements OnInit {
    .
    .
    .
    .
    ngOnInit() {
    var OneSignal = window['OneSignal'] || [];
    console.log("Init OneSignal");
    OneSignal.push(["init", {
      appId: "xxx-xxx-xxx-xxx",
      autoRegister: false,
      allowLocalhostAsSecureOrigin: true,
      notifyButton: {
        enable: false
      }
    }]);
    console.log('OneSignal Initialized');
    OneSignal.push(function () {
      console.log('Register For Push');
      OneSignal.push(["registerForPushNotifications"])
    });
    OneSignal.push(function () {
      // Occurs when the user's subscription changes to a new value.
      OneSignal.on('subscriptionChange', function (isSubscribed) {
        console.log("The user's subscription state is now:", isSubscribed);
        OneSignal.getUserId().then(function (userId) {
          console.log("User ID is", userId);
        });
      });
    });
    }
    .
    .
    .
}

Couple of things to note:

  • Listen to the subscriptionChange and then get the userid
  • subscriptionChange is also fired when user disables the notification manually from the browser.
  • autoRegister: false, will not prompt the 'Allow'/'Deny' option. So we have to call registerForPushNotifications. One can use this to prompt for push notification on a button click or something.

EDIT 2018

I've made a util class which I use across all my angular projects to reduce boilerplate code for onesignal.

https://gist.github.com/PsyGik/54a5e6cf5e92ba535272c38c2be773f1