[Ionic 4] Capacitor no Push Notification any alternative?

Planning to implement Push Notifications to my app but Capacitor has no push notification plugin as of the moment. Anyone had any luck using other plugins or services for their push notifications for Ionic 4? Anyone tried OneSignal for Ionic 4?

I used cordova-fcm before, but since I don’t want to integrate Cordova to my project, I’m afraid that is not an option. cordova-fcm looks for a Google-Info.plist in cordova directory.

Thanks.

I have a tutorial on using PhoneGap Plugin Push with Capacitor: https://www.joshmorony.com/sending-push-notifications-with-the-phonegap-push-plugin-in-capacitor/

I think push notification support has been added to Capacitor, or will be soon (not sure if it has been implemented but not released, or just not implemented yet).

2 Likes

Thanks, now I feel stupid on how I could miss your tutorial. Great work as usual!

Hi,
I’m struggling to use the Capacitor PushNotification functionality and having issues, and searching on Google landed me on this topic.

I register the device on FCM using Capacitor PN method successfully, I get a token back, which I store in my users database as well. I verify that when I try to push a new notification through Firebase console, it shows me that 1 device will be getting the notification, which means the device is registered properly.

However although I add a Listener properly (i.e. PushNotifictions.addListener(‘pushNotificationReceived’, (notification: PushNotification) => { //code to process notification }, the listener is never triggered when a push notification is send via the Firebase console.

Full code here:

    PushNotifications.addListener('registrationError', (error: any) => {
      console.log('error on register ' + JSON.stringify(error));
    });
    PushNotifications.addListener('registration', (token: PushNotificationToken) => {
      console.log('token ' + token.value);
      this.user.pnToken = token.value;
      Device.getInfo().then((data) => {
        this.user.devUUID = data.uuid;
        this.user.platform = data.platform;
      }).then(() => {
        this.auth.saveUser(this.user);
        PushNotifications.addListener('pushNotificationReceived', (notification: PushNotification) => {
// ----->>> this is never hit 
          console.log('notification ' + JSON.stringify(notification));
        });
      })
    });
    PushNotifications.register();

(note: I tried reordering the register & addlistener calls the other way round, but behaviour is the same)

Ionic Info:

Ionic:

   ionic (Ionic CLI)             : 4.3.0
   Ionic Framework               : @ionic/angular 4.0.0-beta.15
   @angular-devkit/build-angular : 0.8.6
   @angular-devkit/schematics    : 0.8.6
   @angular/cli                  : 6.2.6
   @ionic/angular-toolkit        : 1.1.0

Capacitor:

   capacitor (Capacitor CLI) : 1.0.0-beta.8
   @capacitor/core           : 1.0.0-beta.8

Any idea what is going wrong?

Thanks
Chris

Just noting that the issue is resolved. Stupidly enough I was trying to get this working in the Emulator… When I deployed on a physical device it works :)…

@vorkapps We all have been there before :wink:

@vorkapps, Would you mind sharing how you registered Capacitor PN with FCM? I’m trying to implement this on a project and am coming up short. I’m able to successfully register Capacitor PN and get a token, but am unsure how to connect FCM.
Thank you!

Hi, I’m not sure what you mean by “connect FCM”… After the Register() call, I just call the PushNotifications.addListener(‘pushNotificationReceived’, (notification: PushNotification) => {}) and when a notification comes in, it is passed to the handler.
As far as sending a notification to the device, I just do it via Postman for now, passing the token obtained on the device in the payload.
Have in mind, that if you are testing this on an emulator, you need to be using an image with Google Play Services, or on a physical device
I hope this helps…

Thanks @vorkapps. The problem is I am not able to send a PN with the token received from capacitor. Not sure how to go about registering it with FCM.

You don’t “register it with FCM” the fact that you have a token means it’s registered and FCM knows about it. The firebase library you are using to register the device, has already “talked” with FCM who issues the token.
In the payload you create you need to have a { “to”: “token here”, … } to send it to a specific device.
Or you can use the push notifications page in firebase console and instead of pushing to all devices in an application, you press the “send to device” button and paste your token there
It will tell you that it will send to 1 device and when you press ok, it will send it.

The problem is that Capacitor returns the APN token not the FCM token. So when I try to use that APN token to “send to a test device” in Firebase, it doesn’t work. I see the FCM token in Xcode, but am not able to retrieve it in my front-end (Angular). I put together a cloud function that takes the APN token that capacitor returns, and gets the FCM token from Google.

exports.registerFCM = functions.firestore.document('users/{userId}/devices/{deviceId}').onCreate((snapshot,context) => {
  const device = snapshot.data();
  if(device.apn_token){
    const request = require("request");
    var options = { method: 'POST',
      url: 'https://iid.googleapis.com/iid/v1:batchImport',
      headers: 
      { 
        'cache-control': 'no-cache',
        'Content-Type': 'application/json',
        Authorization: 'key=<YOUR-SERVER-KEY-FROM-FIREBASE>' },
      body: 
      { application: '<YOUR-PACKAGE-ID IE: com.test.app>',
        sandbox: true,
        apns_tokens: [ `${device.apn_token}` ] },
      json: true };

    return request(options, function (error, response, body) {
      if (error) throw new Error(error);
      return admin.firestore().doc(snapshot.ref.path).update({fcm_token: body.results[0].registration_token})
      .then(val => console.log(body.results[0].registration_token))
      .catch(err => console.log(err))
    });
  }
  else{
    return;
  }
})

I can now subscribe to topics from my frontend.

For anyone looking at this now.

I used this Capacitor package:

You can call getToken() to get the FCM token from iOS.

fcm
    .getToken()
    .then(r => alert(`Token ${r.token}`))
    .catch(err => console.log(err));