diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md
index 54d15b49..cecd41b5 100644
--- a/MIGRATION_GUIDE.md
+++ b/MIGRATION_GUIDE.md
@@ -218,9 +218,12 @@ The Push Subscription namespace is accessible via `OneSignal.User.pushSubscripti
| **React Native** | **Description** |
| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `OneSignal.User.pushSubscription.getPushSubscriptionId()` | _The readonly push subscription ID._ |
-| `OneSignal.User.pushSubscription.getPushSubscriptionToken()` | _The readonly push token._ |
-| `OneSignal.User.pushSubscription.getOptedIn()` | _Gets a boolean value indicating whether the current user is opted in to push notifications. This returns `true` when the app has notifications permission and `optedOut` is called. **_Note:_** Does not take into account the existence of the subscription ID and push token. This boolean may return `true` but push notifications may still not be received by the user._ |
+| `OneSignal.User.pushSubscription.getPushSubscriptionId()` | _**DEPRECATED**
use `getIdAsync`._ |
+| `OneSignal.User.pushSubscription.getPushSubscriptionToken()` | _**DEPRECATED**
use `getTokenAsync`_ |
+| `OneSignal.User.pushSubscription.getOptedIn()` | _**DEPRECATED**
use `getOptedInAsync`_ |
+| `await OneSignal.User.pushSubscription.getIdAsync()` | _The readonly push subscription ID._ |
+| `await OneSignal.User.pushSubscription.getTokenAsync()` | _The readonly push token._ |
+| `await OneSignal.User.pushSubscription.getOptedInAsync()` | _Gets a boolean value indicating whether the current user is opted in to push notifications. This returns `true` when the app has notifications permission and `optedOut` is called. **_Note:_** Does not take into account the existence of the subscription ID and push token. This boolean may return `true` but push notifications may still not be received by the user._ |
| `OneSignal.User.pushSubscription.optIn()` | _Call this method to receive push notifications on the device or to resume receiving of push notifications after calling `optOut`. If needed, this method will prompt the user for push notifications permission._ |
| `OneSignal.User.pushSubscription.optOut()` | _If at any point you want the user to stop receiving push notifications on the current device (regardless of system-level permission status), you can call this method to opt out._ |
| `OneSignal.User.pushSubscription.addEventListener('change', listener: (event) => void)`
**_See below for usage_** | _Adds the listener to run when the push subscription changes._ |
@@ -254,7 +257,8 @@ The Notifications namespace is accessible via `OneSignal.Notifications` and prov
| **React Native** | **Description** |
|--------------------------------------- | --------------- |
-| `OneSignal.Notifications.hasPermission()` | _Whether this app has push notification permission._ |
+| `OneSignal.Notifications.hasPermission()` | _**DEPRECATED**
use `getPermissionAsync()`_ |
+| `OneSignal.Notifications.getPermissionAsync()` | _Whether this app has push notification permission._ |
| `await OneSignal.Notifications.canRequestPermission()` | _Whether attempting to request notification permission will show a prompt. Returns `true` if the device has not been prompted for push notification permission already._ |
| `await OneSignal.Notifications.permissionNative()` | _(ios only) Returns the enum for the native permission of the device. It will be one of: NotDetermined, Denied, Authorized, Provisional (only available in iOS 12), Ephemeral (only available in iOS 14)_ |
| `OneSignal.Notifications.clearAll();` | _Removes all OneSignal notifications._ |
diff --git a/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java b/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java
index b856594e..debabf3e 100644
--- a/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java
+++ b/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java
@@ -434,6 +434,12 @@ public void onNotificationPermissionChange(boolean permission) {
@ReactMethod
public void requestNotificationPermission(final boolean fallbackToSettings, Promise promise) {
+ // if permission already exists, return early as the method call will not resolve
+ if (OneSignal.getNotifications().getPermission()) {
+ promise.resolve(true);
+ return;
+ }
+
OneSignal.getNotifications().requestPermission(fallbackToSettings, Continue.with(result -> {
if (result.isSuccess()) {
promise.resolve(result.getData());
@@ -448,6 +454,16 @@ public void hasNotificationPermission(Promise promise) {
promise.resolve(OneSignal.getNotifications().getPermission());
}
+ @ReactMethod
+ public void permissionNative(Promise promise) {
+ if (OneSignal.getNotifications().getPermission()) {
+ promise.resolve(2);
+ }
+ else {
+ promise.resolve(1);
+ }
+ }
+
@ReactMethod
public void canRequestNotificationPermission(Promise promise) {
promise.resolve(OneSignal.getNotifications().getCanRequestPermission());
@@ -473,13 +489,23 @@ public void removeGroupedNotifications(String id) {
@ReactMethod
public void getPushSubscriptionId(Promise promise) {
IPushSubscription pushSubscription = OneSignal.getUser().getPushSubscription();
- promise.resolve(pushSubscription.getId());
+ String pushId = pushSubscription.getId();
+ if (pushId != null && !pushId.isEmpty()){
+ promise.resolve(pushId);
+ } else {
+ promise.resolve(null);
+ }
}
@ReactMethod
public void getPushSubscriptionToken(Promise promise) {
IPushSubscription pushSubscription = OneSignal.getUser().getPushSubscription();
- promise.resolve(pushSubscription.getToken());
+ String pushToken = pushSubscription.getToken();
+ if (pushToken != null && !pushToken.isEmpty()) {
+ promise.resolve(pushToken);
+ } else {
+ promise.resolve(null);
+ }
}
@ReactMethod
diff --git a/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java b/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java
index ee7c60f6..a9b034a9 100644
--- a/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java
+++ b/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java
@@ -182,9 +182,16 @@ public static HashMap convertInAppMessageClickEventToMap(IInAppM
public static HashMap convertPushSubscriptionStateToMap(PushSubscriptionState state) {
HashMap hash = new HashMap<>();
-
- hash.put("token", state.getToken());
- hash.put("id", state.getId());
+ if (state.getToken() != null && !state.getToken().isEmpty()) {
+ hash.put("token", state.getToken());
+ } else {
+ hash.put("token", JSONObject.NULL);
+ }
+ if (state.getId() != null && !state.getId().isEmpty()) {
+ hash.put("id", state.getId());
+ } else {
+ hash.put("id", JSONObject.NULL);
+ }
hash.put("optedIn", state.getOptedIn());
return hash;
diff --git a/examples/RNOneSignalTS/src/OSButtons.tsx b/examples/RNOneSignalTS/src/OSButtons.tsx
index d9a4914f..ce3ebfc4 100644
--- a/examples/RNOneSignalTS/src/OSButtons.tsx
+++ b/examples/RNOneSignalTS/src/OSButtons.tsx
@@ -133,8 +133,8 @@ class OSButtons extends React.Component {
const hasPermissionButton = renderButtonView(
'Has Notification Permission',
- () => {
- const granted = OneSignal.Notifications.hasPermission();
+ async () => {
+ const granted = await OneSignal.Notifications.getPermissionAsync();
loggingFunction(`Has Notification Permission: ${granted}`);
},
);
@@ -368,8 +368,7 @@ class OSButtons extends React.Component {
const getPushSubscriptionIdButton = renderButtonView(
'Get Push Subscription Id',
async () => {
- const id =
- await OneSignal.User.pushSubscription.getPushSubscriptionId();
+ const id = await OneSignal.User.pushSubscription.getIdAsync();
loggingFunction('Push Subscription Id: ', id);
},
);
@@ -377,14 +376,13 @@ class OSButtons extends React.Component {
const getPushSubscriptionTokenButton = renderButtonView(
'Get Push Subscription Token',
async () => {
- const token =
- await OneSignal.User.pushSubscription.getPushSubscriptionToken();
+ const token = await OneSignal.User.pushSubscription.getTokenAsync();
loggingFunction('Push Subscription Token: ', token);
},
);
const getOptedInButton = renderButtonView('Is Opted In', async () => {
- const optedIn = await OneSignal.User.pushSubscription.getOptedIn();
+ const optedIn = await OneSignal.User.pushSubscription.getOptedInAsync();
loggingFunction('Subscribed for the push notifications: ', optedIn);
});
diff --git a/ios/RCTOneSignal/RCTOneSignal.m b/ios/RCTOneSignal/RCTOneSignal.m
index 1e4486cf..85118514 100644
--- a/ios/RCTOneSignal/RCTOneSignal.m
+++ b/ios/RCTOneSignal/RCTOneSignal.m
@@ -78,7 +78,23 @@ - (void)sendEvent:(NSString *)eventName withBody:(NSDictionary *)body {
}
- (void)onPushSubscriptionDidChangeWithState:(OSPushSubscriptionChangedState * _Nonnull)state {
- [self sendEvent:OSEventString(SubscriptionChanged) withBody:[state jsonRepresentation]];
+ NSMutableDictionary *result = [NSMutableDictionary new];
+
+ //Previous state
+ NSMutableDictionary *previousObject = [NSMutableDictionary new];
+ previousObject[@"token"] = (state.previous.token && ![state.previous.token isEqualToString:@""]) ? state.previous.token : [NSNull null];
+ previousObject[@"id"] = (state.previous.id && ![state.previous.id isEqualToString:@""]) ? state.previous.id : [NSNull null];
+ previousObject[@"optedIn"] = @(state.previous.optedIn);
+ result[@"previous"] = previousObject;
+
+ //Current state
+ NSMutableDictionary *currentObject = [NSMutableDictionary new];
+ currentObject[@"token"] = (state.current.token && ![state.current.token isEqualToString:@""]) ? state.current.token : [NSNull null];
+ currentObject[@"id"] = (state.current.id && ![state.current.id isEqualToString:@""]) ? state.current.id : [NSNull null];
+ currentObject[@"optedIn"] = @(state.current.optedIn);
+ result[@"current"] = currentObject;
+
+ [self sendEvent:OSEventString(SubscriptionChanged) withBody:result];
}
- (void)onNotificationPermissionDidChange:(BOOL)permission {
diff --git a/ios/RCTOneSignal/RCTOneSignalEventEmitter.m b/ios/RCTOneSignal/RCTOneSignalEventEmitter.m
index 5861b208..0d72549c 100644
--- a/ios/RCTOneSignal/RCTOneSignalEventEmitter.m
+++ b/ios/RCTOneSignal/RCTOneSignalEventEmitter.m
@@ -392,13 +392,23 @@ + (void)sendEventWithName:(NSString *)name withBody:(NSDictionary *)body {
RCT_REMAP_METHOD(getPushSubscriptionId,
getPushSubscriptionIdResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
- resolve(OneSignal.User.pushSubscription.id);
+ NSString *pushId = OneSignal.User.pushSubscription.id;
+ if (pushId && ![pushId isEqualToString:@""]) {
+ resolve(pushId);
+ } else {
+ resolve([NSNull null]);
+ }
}
RCT_REMAP_METHOD(getPushSubscriptionToken,
getPushSubscriptionTokenResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
- resolve(OneSignal.User.pushSubscription.token);
+ NSString *token = OneSignal.User.pushSubscription.token;
+ if (token && ![token isEqualToString:@""]) {
+ resolve(token);
+ } else {
+ resolve([NSNull null]);
+ }
}
RCT_EXPORT_METHOD(optIn) {
diff --git a/src/index.ts b/src/index.ts
index ed6d2e67..1958466f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -217,22 +217,67 @@ export namespace OneSignal {
eventManager.removeEventListener(SUBSCRIPTION_CHANGED, listener);
}
- /** The readonly push subscription ID */
+ /**
+ * @deprecated This method is deprecated. It has been replaced by {@link getIdAsync}.
+ */
export function getPushSubscriptionId(): string {
if (!isNativeModuleLoaded(RNOneSignal)) {
return '';
}
+ console.warn(
+ 'OneSignal: This method has been deprecated. Use getIdAsync instead for getting push subscription id.',
+ );
- return pushSub.id;
+ return pushSub.id ? pushSub.id : '';
}
- /** The readonly push subscription token */
+ export async function getIdAsync(): Promise {
+ if (!isNativeModuleLoaded(RNOneSignal)) {
+ return Promise.reject(
+ new Error('OneSignal native module not loaded'),
+ );
+ }
+
+ return await RNOneSignal.getPushSubscriptionId();
+ }
+
+ /**
+ * @deprecated This method is deprecated. It has been replaced by {@link getTokenAsync}.
+ */
export function getPushSubscriptionToken(): string {
if (!isNativeModuleLoaded(RNOneSignal)) {
return '';
}
+ console.warn(
+ 'OneSignal: This method has been deprecated. Use getTokenAsync instead for getting push subscription token.',
+ );
- return pushSub.token;
+ return pushSub.token ? pushSub.token : '';
+ }
+
+ /** The readonly push subscription token */
+ export async function getTokenAsync(): Promise {
+ if (!isNativeModuleLoaded(RNOneSignal)) {
+ return Promise.reject(
+ new Error('OneSignal native module not loaded'),
+ );
+ }
+
+ return await RNOneSignal.getPushSubscriptionToken();
+ }
+
+ /**
+ * @deprecated This method is deprecated. It has been replaced by {@link getOptedInAsync}.
+ */
+ export function getOptedIn(): boolean {
+ if (!isNativeModuleLoaded(RNOneSignal)) {
+ return false;
+ }
+ console.warn(
+ 'OneSignal: This method has been deprecated. Use getOptedInAsync instead for getting push subscription opted in status.',
+ );
+
+ return pushSub.optedIn;
}
/**
@@ -241,12 +286,14 @@ export namespace OneSignal {
* Note: Does not take into account the existence of the subscription ID and push token.
* This boolean may return true but push notifications may still not be received by the user.
*/
- export function getOptedIn(): boolean {
+ export async function getOptedInAsync(): Promise {
if (!isNativeModuleLoaded(RNOneSignal)) {
- return false;
+ return Promise.reject(
+ new Error('OneSignal native module not loaded'),
+ );
}
- return pushSub.optedIn;
+ return await RNOneSignal.getOptedIn();
}
/** Disable the push notification subscription to OneSignal. */
@@ -263,7 +310,6 @@ export namespace OneSignal {
RNOneSignal.optIn();
}
}
-
/** Explicitly set a 2-character language code for the user. */
export function setLanguage(language: string) {
if (!isNativeModuleLoaded(RNOneSignal)) return;
@@ -404,13 +450,24 @@ export namespace OneSignal {
export namespace Notifications {
/**
- * Whether this app has push notification permission. Returns true if the user has accepted permissions,
- * or if the app has ephemeral or provisional permission.
+ * @deprecated This method is deprecated. It has been replaced by {@link getPermissionAsync}.
*/
export function hasPermission(): boolean {
+ console.warn(
+ 'OneSignal: This method has been deprecated. Use getPermissionAsync instead for getting notification permission status.',
+ );
+
return notificationPermission;
}
+ /**
+ * Whether this app has push notification permission. Returns true if the user has accepted permissions,
+ * or if the app has ephemeral or provisional permission.
+ */
+ export async function getPermissionAsync(): Promise {
+ return RNOneSignal.hasNotificationPermission();
+ }
+
/**
* Prompt the user for permission to receive push notifications. This will display the native system prompt to request push
* notification permission. Use the fallbackToSettings parameter to prompt to open the settings app if a user has already
@@ -422,10 +479,6 @@ export namespace OneSignal {
if (!isNativeModuleLoaded(RNOneSignal)) {
return Promise.reject(new Error('OneSignal native module not loaded'));
}
- // if permission already exists, return early as the native call will not resolve
- if (hasPermission()) {
- return Promise.resolve(true);
- }
return RNOneSignal.requestNotificationPermission(fallbackToSettings);
}
@@ -475,13 +528,7 @@ export namespace OneSignal {
return Promise.reject(new Error('OneSignal native module not loaded'));
}
- if (Platform.OS === 'ios') {
- return RNOneSignal.permissionNative();
- } else {
- return notificationPermission
- ? Promise.resolve(OSNotificationPermission.Authorized)
- : Promise.resolve(OSNotificationPermission.Denied);
- }
+ return RNOneSignal.permissionNative();
}
/**
diff --git a/src/models/Subscription.ts b/src/models/Subscription.ts
index ac21cf24..d4771f55 100644
--- a/src/models/Subscription.ts
+++ b/src/models/Subscription.ts
@@ -7,8 +7,8 @@ export enum OSNotificationPermission {
}
export interface PushSubscriptionState {
- id: string;
- token: string;
+ id?: string;
+ token?: string;
optedIn: boolean;
}