'OneSignal issue for Ionic 6 & Capacitor

I'm trying to set OneSignal for push notifications on devices. I did the step by step to setup methods which are shown in the OneSignal Documentation, but no luck.

I also did the official Ionic - Capacitor - Cordova methods to setup OneSignal, with no luck again.

This is the first method I did, following Ionic official Docs:

app.module.ts

...
import { OneSignal } from '@awesome-cordova-plugins/onesingal';

@NgModule({
    ...
    providers: [OneSignal]
});

I created a PushService where I include methods from OneSignal.

push.service.ts:

import { OneSignal } '@awesome-cordova-plugins/onesignal';

export class PushService {
    constructor ( private signal: OneSignal ) {}

    start (): void {
        this.signal.startInit ( 'MY_ONESIGNAL_APP_ID', 'FIREBASE_ID' );
        this.signal.handleNotificationReceived().subscribe(() => {
            // do something when notification is received
        });
        ...
        this.signal.endInit();
    }
}

I call "start" method on my app.component.ts, initializing on this.platform.ready... And when I test on my device, the answer from debug is "plugin_not_installed" OneSignal


Second method I use, following instructions from the Official OneSignal Docs "Ionic & Capacitor"

Directly I put methods on my "start" in push.service.ts, I didn't call it on app.module.ts because is a function:

import { OneSignal } from 'onesignal-cordova-plugin';

export class PushService {
    constructor () {}
    start (): void {
        OneSignal.setAppId ( 'ONESIGNAL_APP_ID' );
        ...
        OneSignal.setNotificationWillShowInForegroundHandler ( ( d ) => console.log ( d ) );
    }
}

In this case, the error is "TypeError: Cannot read properties of undefined (reading 'setAppId')" So, any of those methods is not working.

My system info develop is:

Ionic:

   Ionic CLI                     : 6.18.1 (C:\Users\user\AppData\Roaming\npm\node_modules\@ionic\cli)
   Ionic Framework               : @ionic/angular 6.0.1
   @angular-devkit/build-angular : 13.1.2
   @angular-devkit/schematics    : 12.2.13
   @angular/cli                  : 13.1.2
   @ionic/angular-toolkit        : 5.0.3

Capacitor:

   Capacitor CLI      : 3.3.3
   @capacitor/android : 3.3.3
   @capacitor/core    : 3.3.3
   @capacitor/ios     : not installed

Utility:

   cordova-res : not installed globally
   native-run  : 1.5.0

System:

   NodeJS : v16.13.1 (C:\Program Files\nodejs\node.exe)
   npm    : 8.2.0
   OS     : Windows 10


Solution 1:[1]

I think you need to install the plugin - this is what I have in package.json

"onesignal-cordova-plugin": "^3.0.1"

And import like this -

import OneSignal from 'onesignal-cordova-plugin';

And also in angular.json add this part with allowedCommonJsDependencies

{
  "projects": {
    "app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "allowedCommonJsDependencies": [
              "onesignal-cordova-plugin"
            ]
          }
        }
      }
    }
  }
}

Solution 2:[2]

The official One Signal docs need improvement but they helped me to find the path to get push notifications working with Capacitor 3 and Ionic 6 using Vue on web mobile and also on Android. This is working on my projects.

The points of attention are these:

  • If you'll use mobile push or native push, you have to initialize Onesignal detecting the platform.
  • You also have to include Onesignal service worker js files somewhere they could be located by the browser.
// Call this function when your app start
function OneSignalInit() {
  OneSignal.setAppId("xxxxx-xxxxxx-xxxxxx"); //Your APP ID
  OneSignal.setNotificationOpenedHandler(function(jsonData) {
      console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData));
  });

  OneSignal.promptForPushNotificationsWithUserResponse(function(accepted) {
      console.log("User accepted notifications: " + accepted);
  });
}

if (getPlatforms().includes("capacitor")) {
  OneSignalInit();
} else {
  window.OneSignal = window.OneSignal || [];
  window.OneSignal.push(function () {

    // You have to include some JS files from Onesignal as the docs say to do
    // Place them in a place findable by the browser when the URL is resolved
    window.OneSignal.SERVICE_WORKER_PARAM = { scope: '/assets/js/onesignal/' };
    window.OneSignal.SERVICE_WORKER_PATH = 'assets/js/onesignal/OneSignalSDKWorker.js'
    window.OneSignal.SERVICE_WORKER_UPDATER_PATH = 'assets/js/onesignal/OneSignalSDKUpdaterWorker.js'

    window.OneSignal.init({
      appId: "xxxxx-xxxxx-xxxxx", //Your APP ID
      safari_web_id: "web.onesignal.auto.xxxxxxxxxxx",
      notifyButton: {
        enable: false,
      },
      subdomainName: "odontoenlace",
      promptOptions: {
        slidedown: {
          prompts: [
            {
              type: "push", // current types are "push" & "category"
              autoPrompt: true,
              text: {
                /* limited to 90 characters */
                actionMessage: "Nos gustaría enviarte notificaciones para que estés al tanto de eventos en tu perfil.",
                /* acceptButton limited to 15 characters */
                acceptButton: "Aceptar",
                /* cancelButton limited to 15 characters */
                cancelButton: "Cancelar"
              },
              delay: {
                pageViews: 0,
                timeDelay: 1
              }
            }
          ]
        }
      }
    });
  });
}
  • After all that, you can use this code to detect if Onesignal is recognized and get your Onesignal user_id also known as player_id. Again, checking if you are on web or native.
if (getPlatforms().includes("capacitor")) {
        OneSignal.setAppId("xxxxx-xxxxx-xxxxxx"); // Your APP ID
        OneSignal.getDeviceState((stateChanges) => {
          console.log(
            "OneSignal getDeviceState: " + JSON.stringify(stateChanges)
          );
          if (stateChanges && stateChanges.hasNotificationPermission) {
            console.log("Player ID: " + stateChanges.userId);
          } else {
            console.log("Push notifications are disabled");
          }
        });
      } else {
        console.log("Platform is not capacitor");
        is_push_supported.value =
          window.OneSignal.isPushNotificationsSupported();
        if (is_push_supported.value) {
          if (!getPlatforms().includes("capacitor")) {
            window.OneSignal.getUserId((userId) => {
              console.log("Player ID: " + userId);
            });
          }
        }
      }
  • Finally, if you're compiling your app, Capacitor's default settings for release mode, suppress externals Onesignal libraries so check on your build.gradle file that you have disabled proguard, and minifyEnabled is set to false. The best way is to leave empty the relase object
    buildTypes {
        release {
        }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Monomachus
Solution 2 Javier Escobar