not getting onesignal push notifications on android app


in my MainActivity.java

// ─────────────────────────────────────────────
// OneSignal Identity + Permission Handling
// ─────────────────────────────────────────────

private IUserStateObserver identityObserver = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    SharedPreferences prefs = getSharedPreferences("biratbazar_prefs", Context.MODE_PRIVATE);
    boolean isLoggedIn = prefs.getBoolean("is_logged_in", false);
    String savedUserId = prefs.getString("user_id", null);

    // Observe user identity state
    identityObserver = state -> {
        String currentExternalId = state.getCurrent().getExternalId();
        String currentOnesignalId = state.getCurrent().getOnesignalId();

        Log.d("OneSignal", "User State Change: ExternalID=" 
                + currentExternalId + ", OneSignalID=" + currentOnesignalId);

        boolean isIdentified = isLoggedIn
                ? (currentExternalId != null && currentExternalId.equals(savedUserId))
                : (currentOnesignalId != null);

        if (isIdentified && identityObserver != null) {
            Log.d("OneSignal", "Identity confirmed. Requesting permission...");

            IUserStateObserver toRemove = identityObserver;
            identityObserver = null;
            OneSignal.getUser().removeObserver(toRemove);

            runOnUiThread(this::requestOneSignalPermission);
        }
    };

    OneSignal.getUser().addObserver(identityObserver);

    // Debug: subscription state
    OneSignal.getUser().getPushSubscription().addObserver(state -> {
        boolean hasToken = state.getCurrent().getToken() != null
                && !state.getCurrent().getToken().isEmpty();

        Log.d("OneSignal", "Subscription Changed: ID="
                + state.getCurrent().getId()
                + ", OptedIn=" + state.getCurrent().getOptedIn()
                + ", HasToken=" + hasToken);
    });

    // Login with external ID if available
    if (isLoggedIn && savedUserId != null) {
        OneSignalManager.getInstance().login(savedUserId);
    }
}

// ─────────────────────────────────────────────
// Request Permission
// ─────────────────────────────────────────────

private void requestOneSignalPermission() {
    OneSignal.getNotifications().requestPermission(true, Continue.with(result -> {
        if (result.isSuccess() && Boolean.TRUE.equals(result.getData())) {
            Log.d("OneSignal", "Permission granted → opting in");
            OneSignal.getUser().getPushSubscription().optIn();
        } else {
            Log.d("OneSignal", "Permission not granted or failed: " + result);
        }
    }));
}

// ─────────────────────────────────────────────
// Ensure opt-in on resume
// ─────────────────────────────────────────────

@Override
protected void onResume() {
    super.onResume();

    if (OneSignal.getNotifications().getPermission()) {
        OneSignal.getUser().getPushSubscription().optIn();
    }
}

in my BiratBazarApp.java

package com.officersiam.biratbazar;

import android.app.Application;
import android.util.Log;
import com.google.firebase.FirebaseApp;
import com.onesignal.Continue;
import com.onesignal.OneSignal;
import com.onesignal.debug.LogLevel;

public class BiratBazarApp extends Application {

    private static final String ONESIGNAL_APP_ID = "58eeb5a7-3adf-4d9d-8915-f45c6a542284";

    @Override
    public void onCreate() {
        super.onCreate();

        // 1. Initialize Firebase first
        try {
            FirebaseApp.initializeApp(this);
        } catch (Exception e) {
            Log.e("Firebase", "Firebase init error", e);
        }

        // 2. Initialize OneSignal
        OneSignalManager.getInstance().initialize(this, ONESIGNAL_APP_ID);
    }
}

in my OneSignalManager.java

package com.officersiam.biratbazar;

import android.content.Context;
import android.util.Log;
import com.onesignal.OneSignal;
import com.onesignal.debug.LogLevel;
import com.onesignal.user.subscriptions.IPushSubscriptionObserver;
import com.onesignal.user.subscriptions.PushSubscriptionChangedState;
import com.onesignal.inAppMessages.IInAppMessageLifecycleListener;
import com.onesignal.inAppMessages.IInAppMessageWillDismissEvent;
import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent;
import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent;
import com.onesignal.inAppMessages.IInAppMessageDidDisplayEvent;
import java.util.concurrent.Executors;
import androidx.annotation.NonNull;

public class OneSignalManager {
    private static OneSignalManager instance;
    private boolean isInitialized = false;

    private OneSignalManager() {}

    public static synchronized OneSignalManager getInstance() {
        if (instance == null) {
            instance = new OneSignalManager();
        }
        return instance;
    }

    public void initialize(Context context, String appId) {
        if (isInitialized) return;

        // Set log level for debugging
        OneSignal.getDebug().setLogLevel(LogLevel.VERBOSE);

        // Initialize OneSignal
        OneSignal.initWithContext(context, appId);
        isInitialized = true;
        Log.d("OneSignalManager", "OneSignal initialized with App ID: " + appId);
    }

    public void login(String externalId) {
        Executors.newSingleThreadExecutor().execute(() -> OneSignal.login(externalId));
    }

    public void logout() {
        Executors.newSingleThreadExecutor().execute(() -> OneSignal.logout());
    }

    public void addPushSubscriptionObserver(IPushSubscriptionObserver observer) {
        OneSignal.getUser().getPushSubscription().addObserver(observer);
    }

    public void addTrigger(String key, String value) {
        Executors.newSingleThreadExecutor().execute(() -> OneSignal.getInAppMessages().addTrigger(key, value));
    }

    public void addIAMLifecycleListener(IInAppMessageLifecycleListener listener) {
        OneSignal.getInAppMessages().addLifecycleListener(listener);
    }

    public void removeIAMLifecycleListener(IInAppMessageLifecycleListener listener) {
        OneSignal.getInAppMessages().removeLifecycleListener(listener);
    }
}

in my BiratBazarNotificationService.java

package com.officersiam.biratbazar.notification;

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

/**
 * Declared in AndroidManifest with:
 *   <action android:name="com.onesignal.NotificationServiceExtension"/>
 *
 * Allows us to intercept / modify notifications before they are displayed.
 */
public class BiratBazarNotificationService implements INotificationServiceExtension {

    @Override
    public void onNotificationReceived(INotificationReceivedEvent event) {
        // Display all notifications as-is.
        // To suppress a notification call event.preventDefault() without display().
        event.getNotification().display();
    }
}

in my progaurd-rules.pro

# ============================================================
#  BiratBazar — ProGuard Rules
# ============================================================

# ── App classes ─────────────────────────────────────────────
-keep class com.officersiam.biratbazar.** { *; }

# ── OneSignal ───────────────────────────────────────────────
-keep class com.onesignal.** { *; }
-keepclassmembers class com.onesignal.** {
    public <init>(...);
}
-keep class com.onesignal.OSRemoteNotificationReceivedHandler { *; }
-dontwarn com.onesignal.**

# ── Firebase / FCM ──────────────────────────────────────────
-keep class com.google.firebase.** { *; }
-keepclassmembers class com.google.firebase.** {
    public <init>(...);
}
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.firebase.**
-dontwarn com.google.android.gms.**

# ── AndroidX WorkManager (OneSignal background jobs) ────────
-keep class androidx.work.** { *; }
-keepclassmembers class androidx.work.** {
    public <init>(...);
}
-dontwarn androidx.work.**

# ── WebView JavaScript Interface ────────────────────────────
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

# ── ViewBinding ─────────────────────────────────────────────
-keep class * implements androidx.viewbinding.ViewBinding {
    public static * inflate(...);
    public static * bind(android.view.View);
}

# ── Material / BottomSheet ──────────────────────────────────
-keep class com.google.android.material.** { *; }
-dontwarn com.google.android.material.**

# ── Lottie ──────────────────────────────────────────────────
-keep class com.airbnb.lottie.** { *; }
-dontwarn com.airbnb.lottie.**

# ── General Android safety nets ─────────────────────────────
# Preserve all native method names
-keepclasseswithmembernames class * {
    native <methods>;
}

# Preserve custom View constructors (used by XML inflation)
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# Keep Parcelable implementations
-keepclassmembers class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

# Keep Serializable implementations
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# Keep R class fields (referenced by name in some libs)
-keepclassmembers class **.R$* {
    public static <fields>;
}

# Keep enums
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# ── Debugging (remove/disable in production if preferred) ───
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

in my AndroidMenifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application
        android:name=".BiratBazarApp"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.BiratBazar"
        android:networkSecurityConfig="@xml/network_security_config"
        android:usesCleartextTraffic="true"
        tools:targetApi="31">

        <!-- OneSignal configuration -->
        <meta-data android:name="onesignal_app_id" android:value="58eeb5a7-3adf-4d9d-8915-f45c6a542284" />
        <meta-data
            android:name="com.onesignal.NotificationServiceExtension"
            android:value="com.officersiam.biratbazar.notification.BiratBazarNotificationService" />

        <!-- Honor/EMUI FCM workaround -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id" />

    </application>

</manifest>

in my build.gradle (app)

plugins {
    id 'com.android.application'
    id 'com.google.gms.google-services'
}

dependencies {

    // Firebase
    implementation platform('com.google.firebase:firebase-bom:34.12.0')
    implementation 'com.google.firebase:firebase-messaging'
    implementation 'com.google.firebase:firebase-analytics'

    // OneSignal
    implementation 'com.onesignal:OneSignal:[5.6.1, 5.9.99]'
}

in my build.gradle (project)

plugins {
    id 'com.android.application' version '8.2.2' apply false
    id 'com.android.library' version '8.2.2' apply false
    id 'com.google.gms.google-services' version '4.4.4' apply false
}

![firebase sdk](https://i.sstatic.net/JkS8u02C.png "firebase sdk")

![onesignal firebase json installed perfectly](https://i.sstatic.net/mLHnmNrD.png "onesignal firebase json installed perfectly")

![cloud masaging enabled](https://i.sstatic.net/wiEvZ69Y.png "cloud masaging enabled")

after all that onesignal dashboard showing never subscribed even after i click on allow button on push permission prompt, enable notifications to get news instantly. that status never changing to subscribe
![onesignal dashboard showing never subscribe which not turning to subscribe](https://i.sstatic.net/pzFjcSaf.png "onesignal dashboard showing never subscribe which not turning to subscribe")

2
May 1 at 11:27 AM
User AvatarSiam Al Mahmud
#java#android#firebase-cloud-messaging#onesignal

Accepted Answer

Your Firebase setup is probably not the main problem here.

In your OneSignal dashboard, the important part is this:

Status details: Permission Not Granted

So OneSignal is creating a subscription record, but Android notification permission is still not granted according to OneSignal.

The issue is mostly in this part of your code:

identityObserver = state -> {
    ...
    if (isIdentified) {
        runOnUiThread(this::requestOneSignalPermission);
    }
};

You are waiting for the OneSignal identity observer before asking notification permission. If that observer does not fire, or the user state is already created before the observer is added, then requestOneSignalPermission() may never run.

Keep it simple. Initialize OneSignal in Application, then ask permission directly from your Activity.

Like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestOneSignalPermission();

    SharedPreferences prefs = getSharedPreferences("biratbazar_prefs", Context.MODE_PRIVATE);
    boolean isLoggedIn = prefs.getBoolean("is_logged_in", false);
    String savedUserId = prefs.getString("user_id", null);

    if (isLoggedIn && savedUserId != null) {
        OneSignal.login(savedUserId);
    }

    OneSignal.getUser().getPushSubscription().addObserver(state -> {
        Log.d("OneSignal", "Subscription ID: " + state.getCurrent().getId());
        Log.d("OneSignal", "Token: " + state.getCurrent().getToken());
        Log.d("OneSignal", "OptedIn: " + state.getCurrent().getOptedIn());
    });
}

private void requestOneSignalPermission() {
    OneSignal.getNotifications().requestPermission(true, result -> {
        Log.d("OneSignal", "Permission result: " + result);

        if (Boolean.TRUE.equals(result.getData())) {
            Log.d("OneSignal", "Permission granted");
            OneSignal.getUser().getPushSubscription().optIn();
        } else {
            Log.d("OneSignal", "Permission denied");
        }
    });
}

Also make sure you have this permission in AndroidManifest.xml:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

For Android 13+, this permission is required.
Your Application class can stay simple:

public class BiratBazarApp extends Application {

    private static final String ONESIGNAL_APP_ID = "58eeb5a7-3adf-4d9d-8915-f45c6a542284";

    @Override
    public void onCreate() {
        super.onCreate();

        FirebaseApp.initializeApp(this);

        OneSignal.getDebug().setLogLevel(LogLevel.VERBOSE);
        OneSignal.initWithContext(this, ONESIGNAL_APP_ID);
    }
}

Also check these things:

  1. google-services.json must be inside the app/ folder.

  2. The package name in Firebase must exactly match: com.officersiam.biratbazar

  3. Run on a real device with Google Play Services.

  4. Uninstall and reinstall the app after changing Firebase / OneSignal config.

  5. Check Logcat for this:

Token: something_here
OptedIn: true

If Token is null, then FCM token is not being generated. In that case the issue is Firebase/FCM configuration, not OneSignal permission code.
The main fix: do not wait for the identity observer to request notification permission. Ask permission directly from the Activity after OneSignal initialization.

User AvatarAneequeMalik
May 2 at 2:55 AM
1