From 0028d134d911bc128f7d6fdfc968fd6e2259e57f Mon Sep 17 00:00:00 2001 From: Tuan Luong Date: Wed, 17 Dec 2025 15:14:16 +0700 Subject: [PATCH 1/2] expose setBadgeCount method --- .../rnonesignalandroid/RNOneSignal.java | 11 +++++++++++ ios/RCTOneSignal/RCTOneSignalEventEmitter.m | 19 +++++++++++++++++++ src/index.ts | 18 ++++++++++++++---- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java b/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java index 35b3a059..045d7afc 100644 --- a/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java +++ b/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java @@ -65,6 +65,8 @@ of this software and associated documentation files (the "Software"), to deal import com.onesignal.notifications.INotificationLifecycleListener; import com.onesignal.notifications.INotificationWillDisplayEvent; import com.onesignal.notifications.IPermissionObserver; +import com.onesignal.notifications.internal.badges.impl.shortcutbadger.ShortcutBadgeException; +import com.onesignal.notifications.internal.badges.impl.shortcutbadger.ShortcutBadger; import com.onesignal.user.state.IUserStateObserver; import com.onesignal.user.state.UserChangedState; import com.onesignal.user.subscriptions.IPushSubscription; @@ -274,6 +276,15 @@ public void setPrivacyConsentRequired(Boolean required) { OneSignal.setConsentRequired(required); } + @ReactMethod + public void setBadgeCount(int count) { + try { + ShortcutBadger.applyCountOrThrow(mReactApplicationContext, count); + } catch (ShortcutBadgeException e) { + e.printStackTrace(); + } + } + // OneSignal.Debug namespace methods @ReactMethod public void setLogLevel(int logLevel) { diff --git a/ios/RCTOneSignal/RCTOneSignalEventEmitter.m b/ios/RCTOneSignal/RCTOneSignalEventEmitter.m index 93abb6fe..f6b375c9 100644 --- a/ios/RCTOneSignal/RCTOneSignalEventEmitter.m +++ b/ios/RCTOneSignal/RCTOneSignalEventEmitter.m @@ -244,6 +244,25 @@ + (void)sendEventWithName:(NSString *)name withBody:(NSDictionary *)body { [OneSignal setConsentRequired:required]; } +RCT_EXPORT_METHOD(setBadgeCount:(double)count) { + if (@available(iOS 16.0, macOS 10.13, macCatalyst 16.0, tvOS 16.0, visionOS 1.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center setBadgeCount:count + withCompletionHandler:^(NSError *error) { + if (error) { + NSLog(@"OneSignal: Could not setBadgeCount: %@", error); + } + }]; + return; + } else { + // If count is 0, set to -1 instead to avoid notifications in tray being cleared + // this breaks in iOS 18, but at that point we're using the new setBadge API + NSInteger newCount = count == 0 ? -1 : count; + UIApplication *application = RCTSharedApplication(); + [application setApplicationIconBadgeNumber:newCount]; + } +} + // OneSignal.Debug namespace methods RCT_EXPORT_METHOD(setLogLevel : (int)logLevel) { [OneSignal.Debug setLogLevel:logLevel]; diff --git a/src/index.ts b/src/index.ts index 2fc85415..04c25964 100644 --- a/src/index.ts +++ b/src/index.ts @@ -132,6 +132,15 @@ export namespace OneSignal { RNOneSignal.setPrivacyConsentGiven(granted); } + /** + * Ultility function to set badge count manually + */ + export function setBadgeCount(count: number) { + if (!isNativeModuleLoaded(RNOneSignal)) return; + + RNOneSignal.setBadgeCount(count); + } + export namespace Debug { /** * Enable logging to help debug if you run into an issue setting up OneSignal. @@ -935,9 +944,6 @@ export namespace OneSignal { RNOneSignal.addOutcomeWithValue(name, Number(value)); } - } -} - export { OSNotificationPermission } from './constants/subscription'; export { NotificationWillDisplayEvent, @@ -951,8 +957,12 @@ export { type PushSubscriptionChangedState, type PushSubscriptionState, type UserChangedState, - type UserState, + type UserState }; + type UserChangedState, + export { default as OSNotification } from './OSNotification'; + export type { InAppMessageClickResult } from './types/inAppMessage'; + export type { NotificationClickResult } from './types/notificationEvents'; export { default as OSNotification } from './OSNotification'; export type { InAppMessageClickResult } from './types/inAppMessage'; From f32c9e51275916ec8c8a585ae2abe4950b48102d Mon Sep 17 00:00:00 2001 From: Tuan Luong Date: Wed, 17 Dec 2025 15:24:14 +0700 Subject: [PATCH 2/2] fix syntax issue --- src/index.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 04c25964..f3983a09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -944,6 +944,9 @@ export namespace OneSignal { RNOneSignal.addOutcomeWithValue(name, Number(value)); } + } +} + export { OSNotificationPermission } from './constants/subscription'; export { NotificationWillDisplayEvent, @@ -957,13 +960,9 @@ export { type PushSubscriptionChangedState, type PushSubscriptionState, type UserChangedState, - type UserState + type UserState, }; - type UserChangedState, - export { default as OSNotification } from './OSNotification'; - export type { InAppMessageClickResult } from './types/inAppMessage'; - export type { NotificationClickResult } from './types/notificationEvents'; export { default as OSNotification } from './OSNotification'; export type { InAppMessageClickResult } from './types/inAppMessage'; -export type { NotificationClickResult } from './types/notificationEvents'; +export type { NotificationClickResult } from './types/notificationEvents'; \ No newline at end of file