Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question]: NotificationServiceExtension: How to notify Ionic application when recieve background/data/silent notification? #999

Open
1 task done
anatoly-spb opened this issue May 29, 2024 · 2 comments

Comments

@anatoly-spb
Copy link

anatoly-spb commented May 29, 2024

How can we help?

I want to receive background/data/silent notification in my Ionic Application based on [email protected] and Capacitor:

import { Component } from '@angular/core';
import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
import OneSignal from 'onesignal-cordova-plugin';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  standalone: true,
  imports: [IonApp, IonRouterOutlet],
})
export class AppComponent {
  constructor() {
    OneSignal.Debug.setLogLevel(6)
    OneSignal.initialize("xxxx")
    OneSignal.Notifications.addEventListener('click', async (e) => {
      let clickData = await e.notification;
      console.log("Notification Clicked : "  + JSON.stringify(clickData));
    })
    OneSignal.Notifications.addEventListener('foregroundWillDisplay', async (e) => {
      let notification = await e.getNotification();
      console.log("Notification Foreground Will Displayed : "  + JSON.stringify(notification));
    })
    OneSignal.Notifications.addEventListener('permissionChange', async (e) => {
      let success = await e;
      console.log("Notification Permission Changed : "  + success);
    })
    OneSignal.Notifications.requestPermission(true).then((success: Boolean) => {
      console.log("Notification permission granted " + success);
    })
    OneSignal.User.pushSubscription.getIdAsync().then(id=>{
      console.log("Notification Subscription ID: " + id);
    })
    // XXXXXXXXXX
  }
}

. According to documentation https://documentation.onesignal.com/docs/data-notifications I have implemented NotificationServiceExtension for Android:

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

import com.onesignal.debug.internal.logging.Logging;
import com.onesignal.notifications.IDisplayableMutableNotification;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;
@Keep
public class NotificationServiceExtension implements INotificationServiceExtension {
  @Override
  public void onNotificationReceived(@NonNull INotificationReceivedEvent event) {
    IDisplayableMutableNotification notification = event.getNotification();

    Logging.info(String.format("NotificationServiceExtension::onNotificationReceived: notificationId=%s, rawPayload=%s", notification.getNotificationId(), notification.getRawPayload()), null);
    // YYYYYYYYYYY
  }
}

But what should I call inside onNotificationReceived instead of YYYYYYYYYYY to pass this notification to Ionic Application based on Capacitor and what should I write instead of XXXXXXXXXX to subscribe on background/data/silent notification?

Thanks in advance,
Anatoly Shirokov

Code of Conduct

  • I agree to follow this project's Code of Conduct
@jkasten2
Copy link
Member

jkasten2 commented Jun 21, 2024

@anatoly-spb

Keep in mind that background/silent are not always the best fit, so it is recommend you provide more details on your goal to see if there are better options.

We don't have a specific guide on doing bridging like this but you could use some like Ionic App Events if you need get some information from Java / Kotlin native to JavaScript.
https://capacitorjs.com/docs/v2/plugins/android#app-events

@chijete
Copy link

chijete commented Jan 21, 2025

There is no direct implementation of this plugin to receive silent notifications from OneSignal, but I have made an implementation that allows you to receive an event when a silent notification is received, even when the app is closed (Java side).

Step 1: Add a function in MainActivity to use the Bridge

This will allow us to send Java events to Javascript.

Edit file MainActivity.java (your-proyect/android/app/src/main/java/com/your/package/MainActivity.java)

package com.your.package; // Replace with your package name

import com.getcapacitor.BridgeActivity;

// Imports:
import android.util.Log;
import android.os.Bundle;

public class MainActivity extends BridgeActivity {
    private static MainActivity instance;
    private static final String TAG = "MainActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        instance = this;
    }

    public static MainActivity getInstance() {
        return instance;
    }

    public void handleNotificationPayload(String payload) {
        Log.d(TAG, "Payload received: " + payload);
        bridge.triggerJSEvent("onCapacitorOneSignalNotificationReceived", "window", payload);
    }
}

Step 2: Intercept notifications coming from OneSignal.

Create file NotificationServiceExtension.java at your-proyect/android/app/src/main/java/com/your/package/

package com.your.package; // Replace with your package name

import com.onesignal.notifications.IActionButton;
import com.onesignal.notifications.IDisplayableMutableNotification;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;

import android.os.Handler;
import android.util.Log;

import org.json.JSONObject;
import java.util.HashMap;

import com.getcapacitor.JSObject;

import androidx.annotation.Keep; // To prevent the minifier from removing this class

@Keep
public class NotificationServiceExtension implements INotificationServiceExtension {
    private static final String TAG = "NotificationServiceExtension";

    @Override
    public void onNotificationReceived(INotificationReceivedEvent event) {
        IDisplayableMutableNotification notification = event.getNotification();

        String rawPayloadStr = notification.getRawPayload();

        Log.d(TAG, "rawPayloadStr: " + rawPayloadStr); // Optional: Log the raw payload in logcat.

        try {

            MainActivity mainActivity = MainActivity.getInstance();
            if (mainActivity != null) {
                mainActivity.handleNotificationPayload(rawPayloadStr);
            } else {
                Log.e(TAG, "MainActivity instance is null");
            }
            
        } catch (Exception e) {
            Log.e(TAG, "MainActivity send error: " + e.getMessage());
        }
    }
}

Advanced:

All notifications received from OneSignal are intercepted in this file.

Here you could do something else with the notification data, even when the app is closed.

Step 3: Add the NotificationServiceExtension to the AndroidManifest

Edit file AndroidManifest.xml (your-proyect/android/app/src/main/AndroidManifest.xml)

Add this:

<meta-data
            android:name="com.onesignal.NotificationServiceExtension"
            android:value="com.your.package.NotificationServiceExtension"
        />

Inside of <application> tag.

(Replace com.your.package with your package name).

Step 4: Receive the event with Javascript

With this code you can listen to the event from Javascript when the application is active.

window.addEventListener('onCapacitorOneSignalNotificationReceived', (event) => {
  console.log('Notification received with payload:', event);
});

How to send a silent notification

With OneSignal API:

curl --request POST \
     --url 'https://api.onesignal.com/notifications?c=push'
--data '
{
  "app_id": "XXX-XXX-XXX",
  "include_subscription_ids": ["YYY-YYY-YYY"],
  "target_channel": "push",
  "content_available": true,
  "data": {
    "info": { "key": "value" }
  }
}

See https://documentation.onesignal.com/reference/push-notification

Footnote:

  • This code does not disable the plugin from receiving notifications. The plugin will still receive visible notifications and display them in the notification bar.
  • This code is designed for Android only.
  • "Silent notifications" are those sent with content_available = true

Documentation and reference:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants