diff --git a/CHANGELOG.md b/CHANGELOG.md index f0b2f4c33..812560427 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## Unreleased + +### Updates + +- Added `Iterable.disableDeviceForAllUsers()` to unregister this device's push token from every user associated with the device (SDK-550). + - iOS: forwards to native `IterableAPI.disableDeviceForAllUsers()`. + - Android: graceful no-op that logs a warning; use `disableDeviceForCurrentUser()` to disable push for the current user. There is no public native "all users" equivalent. + ## 3.1.0 ### Fixes diff --git a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java index b25432d4b..ea7bae18b 100644 --- a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java +++ b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java @@ -373,6 +373,10 @@ public void disableDeviceForCurrentUser() { IterableApi.getInstance().disablePush(); } + public void disableDeviceForAllUsers() { + IterableLogger.w(TAG, "disableDeviceForAllUsers is not supported on Android; use disableDeviceForCurrentUser. There is no public native equivalent."); + } + public void registerDeviceToken(String token) { IterableLogger.v(TAG, "registerDeviceToken"); IterableApi.getInstance().registerDeviceToken(token); diff --git a/android/src/newarch/java/com/RNIterableAPIModule.java b/android/src/newarch/java/com/RNIterableAPIModule.java index fb71142b8..b25c39362 100644 --- a/android/src/newarch/java/com/RNIterableAPIModule.java +++ b/android/src/newarch/java/com/RNIterableAPIModule.java @@ -137,6 +137,11 @@ public void disableDeviceForCurrentUser() { moduleImpl.disableDeviceForCurrentUser(); } + @Override + public void disableDeviceForAllUsers() { + moduleImpl.disableDeviceForAllUsers(); + } + @Override public void registerDeviceToken(String token) { moduleImpl.registerDeviceToken(token); diff --git a/android/src/oldarch/java/com/RNIterableAPIModule.java b/android/src/oldarch/java/com/RNIterableAPIModule.java index c2f9b3161..cb290f3e4 100644 --- a/android/src/oldarch/java/com/RNIterableAPIModule.java +++ b/android/src/oldarch/java/com/RNIterableAPIModule.java @@ -138,6 +138,11 @@ public void disableDeviceForCurrentUser() { moduleImpl.disableDeviceForCurrentUser(); } + @ReactMethod + public void disableDeviceForAllUsers() { + moduleImpl.disableDeviceForAllUsers(); + } + @ReactMethod public void registerDeviceToken(String token) { moduleImpl.registerDeviceToken(token); diff --git a/ios/RNIterableAPI/RNIterableAPI.mm b/ios/RNIterableAPI/RNIterableAPI.mm index 965b2d81e..a766a6814 100644 --- a/ios/RNIterableAPI/RNIterableAPI.mm +++ b/ios/RNIterableAPI/RNIterableAPI.mm @@ -230,6 +230,10 @@ - (void)disableDeviceForCurrentUser { [_swiftAPI disableDeviceForCurrentUser]; } +- (void)disableDeviceForAllUsers { + [_swiftAPI disableDeviceForAllUsers]; +} + - (void)registerDeviceToken:(NSString *)token { [_swiftAPI registerDeviceToken:token]; } @@ -516,6 +520,10 @@ - (void)wakeApp { [_swiftAPI disableDeviceForCurrentUser]; } +RCT_EXPORT_METHOD(disableDeviceForAllUsers) { + [_swiftAPI disableDeviceForAllUsers]; +} + RCT_EXPORT_METHOD(registerDeviceToken : (NSString *)token) { [_swiftAPI registerDeviceToken:token]; } diff --git a/ios/RNIterableAPI/ReactIterableAPI.swift b/ios/RNIterableAPI/ReactIterableAPI.swift index a216a0e69..26def081d 100644 --- a/ios/RNIterableAPI/ReactIterableAPI.swift +++ b/ios/RNIterableAPI/ReactIterableAPI.swift @@ -144,6 +144,12 @@ import React IterableAPI.disableDeviceForCurrentUser() } + @objc(disableDeviceForAllUsers) + public func disableDeviceForAllUsers() { + ITBInfo() + IterableAPI.disableDeviceForAllUsers() + } + @objc(registerDeviceToken:) public func registerDeviceToken(token: String) { ITBInfo() diff --git a/src/__mocks__/MockRNIterableAPI.ts b/src/__mocks__/MockRNIterableAPI.ts index 60013bdbb..68355d2a1 100644 --- a/src/__mocks__/MockRNIterableAPI.ts +++ b/src/__mocks__/MockRNIterableAPI.ts @@ -34,6 +34,8 @@ export class MockRNIterableAPI { static disableDeviceForCurrentUser = jest.fn(); + static disableDeviceForAllUsers = jest.fn(); + static registerDeviceToken = jest.fn((token: string): void => { MockRNIterableAPI.token = token; }); diff --git a/src/api/NativeRNIterableAPI.ts b/src/api/NativeRNIterableAPI.ts index 7e96bc649..c902dc598 100644 --- a/src/api/NativeRNIterableAPI.ts +++ b/src/api/NativeRNIterableAPI.ts @@ -147,6 +147,7 @@ export interface Spec extends TurboModule { // Device management disableDeviceForCurrentUser(): void; + disableDeviceForAllUsers(): void; registerDeviceToken(token: string): void; getLastPushPayload(): Promise<{ [key: string]: string | number | boolean; diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index baccc3e41..6da4b9ca5 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -143,6 +143,16 @@ describe('Iterable', () => { }); }); + describe('disableDeviceForAllUsers', () => { + it('should disable the device for all users', () => { + // GIVEN no parameters + // WHEN Iterable.disableDeviceForAllUsers is called + Iterable.disableDeviceForAllUsers(); + // THEN corresponding method is called on RNIterableAPI + expect(MockRNIterableAPI.disableDeviceForAllUsers).toBeCalled(); + }); + }); + describe('registerDeviceToken', () => { it('should register the device token for the current user', () => { // GIVEN a device token diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index aaaa84073..ffd93295d 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -345,6 +345,26 @@ export class Iterable { IterableApi.disableDeviceForCurrentUser(); } + /** + * Disable this device's push token for every user associated with the device, + * not only the currently signed-in user. + * + * On iOS this forwards to native `IterableAPI.disableDeviceForAllUsers()`. + * On Android this is a no-op that logs a warning: the native Android SDK has + * no public "all users" equivalent. Use {@link disableDeviceForCurrentUser} to + * disable push for the current user on both platforms. + * + * Fire-and-forget: native success or failure is not surfaced to JS. + * + * @example + * ```typescript + * Iterable.disableDeviceForAllUsers(); + * ``` + */ + static disableDeviceForAllUsers() { + IterableApi.disableDeviceForAllUsers(); + } + /** * Register the device's token for the current user, re-enabling push notifications. * diff --git a/src/core/classes/IterableApi.test.ts b/src/core/classes/IterableApi.test.ts index d639d79ed..93cf80f6c 100644 --- a/src/core/classes/IterableApi.test.ts +++ b/src/core/classes/IterableApi.test.ts @@ -282,6 +282,17 @@ describe('IterableApi', () => { }); }); + describe('disableDeviceForAllUsers', () => { + it('should call RNIterableAPI.disableDeviceForAllUsers', () => { + // GIVEN no parameters + // WHEN disableDeviceForAllUsers is called + IterableApi.disableDeviceForAllUsers(); + + // THEN RNIterableAPI.disableDeviceForAllUsers is called + expect(MockRNIterableAPI.disableDeviceForAllUsers).toBeCalled(); + }); + }); + describe('registerDeviceToken', () => { it('should call RNIterableAPI.registerDeviceToken with the token', () => { // GIVEN a device token diff --git a/src/core/classes/IterableApi.ts b/src/core/classes/IterableApi.ts index 2fad862a7..aeb7def6b 100644 --- a/src/core/classes/IterableApi.ts +++ b/src/core/classes/IterableApi.ts @@ -137,6 +137,17 @@ export class IterableApi { return RNIterableAPI.disableDeviceForCurrentUser(); } + /** + * Disable this device's push token for every user associated with the device. + * + * iOS: forwards to native `IterableAPI.disableDeviceForAllUsers()`. + * Android: logged no-op — there is no public native "all users" equivalent. + */ + static disableDeviceForAllUsers() { + IterableLogger.log('disableDeviceForAllUsers'); + return RNIterableAPI.disableDeviceForAllUsers(); + } + /** * Register the device token for the current user, re-enabling push notifications. *