expo-pusher-push-notifications 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,22 @@
1
1
  # expo-pusher-push-notifications
2
2
 
3
- Push notifications for Expo (SDK 58+). Use Pusher Beams, or skip Pusher and send to FCM/APNs yourself. Custom sounds included.
3
+ Push notifications for Expo and React Native, powered by [Pusher Beams](https://pusher.com/beams). Subscribe devices to topics, bind them to your signed-in users, and get custom sounds, Android channels, badges, and local notifications along the way.
4
4
 
5
5
  ```sh
6
6
  npx expo install expo-pusher-push-notifications
7
7
  ```
8
8
 
9
- Expo Go can't load native modules, so you'll need a dev build. See [Setup](docs/setup.md).
9
+ Needs Expo SDK 58+ and a development build (Expo Go can't load native modules).
10
10
 
11
- ## Pick one mode
11
+ ## Quick start
12
12
 
13
- | You want to… | Use | Needs |
14
- |---|---|---|
15
- | Send to everyone following a topic (`news`, `order-42`) | [**Interests**](docs/interests.md) | Pusher Beams |
16
- | Send to a signed-in user on all their devices | [**Users**](docs/users.md) | Pusher Beams + one auth endpoint |
17
- | Send from your own server straight to FCM / APNs | [**DeviceToken**](docs/direct.md) | Nothing from Pusher |
13
+ Add the config plugin to `app.json`:
18
14
 
19
- Each mode has its own object. Use one, ignore the rest.
15
+ ```json
16
+ ["expo-pusher-push-notifications", { "instanceId": "YOUR_BEAMS_INSTANCE_ID" }]
17
+ ```
20
18
 
21
- ### Interests
19
+ Then in your app:
22
20
 
23
21
  ```ts
24
22
  import { Interests } from 'expo-pusher-push-notifications';
@@ -27,26 +25,51 @@ await Interests.start('YOUR_BEAMS_INSTANCE_ID');
27
25
  await Interests.subscribe('news');
28
26
  ```
29
27
 
30
- ### Users
28
+ That device now gets anything your server publishes to `news`. Full console steps (APNs, Firebase, Beams) are in [Setup](docs/setup.md).
29
+
30
+ ## Subscribe to interests (topics)
31
+
32
+ Interests are topics like `news`, `order-42`, or `team-7`. Every device subscribed to one gets the push.
33
+
34
+ ```ts
35
+ await Interests.subscribe('order-42');
36
+ await Interests.unsubscribe('order-42');
37
+ ```
38
+
39
+ More in [Interests](docs/interests.md).
40
+
41
+ ## Bind a device to a user
42
+
43
+ When your backend thinks in user ids ("send this to user-123"), bind the device to the signed-in user. Beams asks your API for an auth token, so you need one small endpoint on your server.
31
44
 
32
45
  ```ts
33
46
  import { Users } from 'expo-pusher-push-notifications';
34
47
 
35
48
  await Users.start('YOUR_BEAMS_INSTANCE_ID');
36
- await Users.login('user-123', { url: 'https://api.example.com/beams-auth' });
37
- // sign-out: await Users.logout();
49
+
50
+ // after your own sign-in
51
+ await Users.login('user-123', {
52
+ url: 'https://api.example.com/pusher/beams-auth',
53
+ headers: { Authorization: `Bearer ${sessionToken}` },
54
+ });
55
+
56
+ // on sign-out
57
+ await Users.logout();
38
58
  ```
39
59
 
40
- ### DeviceToken (no Pusher)
60
+ You can use interests and users together. See [Authenticate users](docs/users.md) for the server side.
41
61
 
42
- ```ts
43
- import { DeviceToken } from 'expo-pusher-push-notifications';
62
+ ## Send from your server
63
+
64
+ ```js
65
+ import PushNotifications from '@pusher/push-notifications-server';
66
+ const beams = new PushNotifications({ instanceId, secretKey });
44
67
 
45
- const { token, type } = await DeviceToken.start(); // type: 'fcm' | 'apns'
46
- DeviceToken.onChange(saveToBackend);
68
+ await beams.publishToInterests(['news'], payload); // everyone on a topic
69
+ await beams.publishToUsers(['user-123'], payload); // one user, all their devices
47
70
  ```
48
71
 
49
- ## Works in every mode
72
+ ## Extras
50
73
 
51
74
  ```ts
52
75
  import { addListener, createChannel, setBadgeCount, scheduleLocalNotification } from 'expo-pusher-push-notifications';
@@ -57,26 +80,22 @@ await setBadgeCount(3);
57
80
  await scheduleLocalNotification({ title: 'Stand up', seconds: 600, sound: 'alarm.wav' });
58
81
  ```
59
82
 
60
- Bundle sounds with the config plugin:
61
-
62
- ```json
63
- ["expo-pusher-push-notifications", { "sounds": ["./assets/alarm.wav"] }]
64
- ```
65
-
66
- More: [sounds, channels, badges, local notifications](docs/extras.md).
83
+ Custom sounds go in the plugin's `sounds` option. Details in [Extras](docs/extras.md).
67
84
 
68
85
  ## Docs
69
86
 
70
- - [Setup](docs/setup.md): install, config plugin options, Firebase / APNs / Beams console steps
71
- - [Interests](docs/interests.md) · [Users](docs/users.md) · [DeviceToken](docs/direct.md)
87
+ - [Setup](docs/setup.md)
88
+ - [Interests](docs/interests.md)
89
+ - [Authenticate users](docs/users.md)
72
90
  - [Sounds, channels, badges, local notifications](docs/extras.md)
73
91
  - [Full API](docs/api.md)
74
92
  - [Migrating from react-native-pusher-push-notifications](docs/migrating.md)
75
93
 
76
- ## Heads up
94
+ ## Good to know
77
95
 
78
- - On iOS this module owns the notification delegate, and on Android it owns the FCM service. Don't run it alongside `expo-notifications` or `@react-native-firebase/messaging`.
79
- - Need realtime Pusher **Channels** (websockets)? That's a different product. Use [`pusher-js`](https://github.com/pusher/pusher-js); it works in Expo as is.
96
+ - This module owns the iOS notification delegate and the Android FCM service, so don't run it alongside `expo-notifications` or `@react-native-firebase/messaging`.
97
+ - Want a raw FCM / APNs token without Beams? Use [`expo-notifications`](https://docs.expo.dev/versions/latest/sdk/notifications/) instead.
98
+ - Need realtime Pusher **Channels** (websockets)? Use [`pusher-js`](https://github.com/pusher/pusher-js).
80
99
 
81
100
  ## License
82
101
 
@@ -9,7 +9,6 @@ import android.content.Intent
9
9
  import android.os.Build
10
10
  import android.os.SystemClock
11
11
  import androidx.core.app.NotificationManagerCompat
12
- import com.google.firebase.messaging.FirebaseMessaging
13
12
  import com.pusher.pushnotifications.BeamsCallback
14
13
  import com.pusher.pushnotifications.PushNotifications
15
14
  import com.pusher.pushnotifications.PusherCallbackError
@@ -76,24 +75,6 @@ class ExpoPusherPushNotificationsModule : Module() {
76
75
  AsyncFunction("clearAllState") { PushNotifications.clearAllState() }
77
76
  AsyncFunction("stop") { PushNotifications.stop() }
78
77
 
79
- // ---- Raw device token (FCM) ----
80
- AsyncFunction("registerForDeviceToken") { promise: Promise ->
81
- FirebaseMessaging.getInstance().token.addOnCompleteListener { t ->
82
- if (t.isSuccessful && t.result != null) {
83
- NotificationHelper.saveToken(context, t.result)
84
- sendEvent("registered", mapOf("deviceToken" to t.result, "type" to "fcm"))
85
- promise.resolve(tokenMap(t.result))
86
- } else promise.reject("E_FCM_TOKEN", t.exception?.message ?: "Failed to get FCM token", t.exception)
87
- }
88
- }
89
- AsyncFunction("getDevicePushToken") { -> NotificationHelper.savedToken(context)?.let { tokenMap(it) } }
90
- AsyncFunction("deleteDevicePushToken") { promise: Promise ->
91
- FirebaseMessaging.getInstance().deleteToken().addOnCompleteListener { t ->
92
- NotificationHelper.saveToken(context, null)
93
- if (t.isSuccessful) promise.resolve(null) else promise.reject("E_FCM_DELETE", t.exception?.message, t.exception)
94
- }
95
- }
96
-
97
78
  // ---- Permissions ----
98
79
  AsyncFunction("requestPermission") { promise: Promise ->
99
80
  val perms = appContext.permissions
@@ -159,8 +140,6 @@ class ExpoPusherPushNotificationsModule : Module() {
159
140
  override fun onFailure(error: PusherCallbackError) = promise.reject("E_SET_USER_ID", error.message, null)
160
141
  }
161
142
 
162
- private fun tokenMap(token: String) = mapOf("type" to "fcm", "platform" to "android", "token" to token)
163
-
164
143
  private fun status(): String =
165
144
  if (NotificationManagerCompat.from(context).areNotificationsEnabled()) PermissionsStatus.GRANTED.status
166
145
  else if (Build.VERSION.SDK_INT >= 33) PermissionsStatus.UNDETERMINED.status else PermissionsStatus.DENIED.status
@@ -106,10 +106,6 @@ object NotificationHelper {
106
106
  if (n <= 0) NotificationManagerCompat.from(ctx).cancelAll()
107
107
  }
108
108
 
109
- fun saveToken(ctx: Context, token: String?) =
110
- ctx.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().putString("fcm_token", token).apply()
111
- fun savedToken(ctx: Context) = ctx.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getString("fcm_token", null)
112
-
113
109
  fun show(ctx: Context, id: Int, title: String?, body: String?, data: Map<String, String>, sound: String?, channelId: String?) {
114
110
  ensureChannels(ctx)
115
111
  val launch = ctx.packageManager.getLaunchIntentForPackage(ctx.packageName)?.apply {
@@ -4,8 +4,8 @@ import com.google.firebase.messaging.RemoteMessage
4
4
  import com.pusher.pushnotifications.fcm.MessagingService
5
5
 
6
6
  /**
7
- * Single FCM service for all three modes. Extends the Beams MessagingService so Beams keeps working
8
- * in `interests`/`users` mode; in `device` mode it simply receives raw FCM messages from your server.
7
+ * The app's FCM service. Extends the Beams MessagingService so Beams keeps working,
8
+ * and adds foreground display, custom sounds/channels and badge handling on top.
9
9
  */
10
10
  class PusherMessagingService : MessagingService() {
11
11
  companion object { @Volatile var module: ExpoPusherPushNotificationsModule? = null }
@@ -39,7 +39,6 @@ class PusherMessagingService : MessagingService() {
39
39
 
40
40
  override fun onNewToken(token: String) {
41
41
  super.onNewToken(token)
42
- NotificationHelper.saveToken(this, token)
43
42
  module?.emit("registered", mapOf("deviceToken" to token, "type" to "fcm"))
44
43
  }
45
44
  }
@@ -1,21 +1,19 @@
1
1
  /**
2
- * Delivery mode.
2
+ * Which Beams auth path the app uses.
3
3
  *
4
- * - `interests`: Pusher Beams interests. Devices subscribe to named interests; server calls Beams `publishToInterests`.
5
- * - `users`: Pusher Beams Authenticated Users. Device is bound to a user via `setUserId`; server calls Beams `publishToUsers`.
6
- * - `device`: Raw device-token push. Beams is NOT started. The module obtains the native FCM (Android) /
7
- * APNs (iOS) device token and hands it to you; your server sends directly to FCM / APNs.
4
+ * - `interests`: devices subscribe to named interests; your server calls Beams `publishToInterests`.
5
+ * - `users`: the device is bound to a user via `setUserId`; your server calls Beams `publishToUsers`.
8
6
  */
9
- export type PusherTransportMode = 'interests' | 'users' | 'device';
7
+ export type PusherTransportMode = 'interests' | 'users';
10
8
  export interface PusherConfig {
11
- /** Pusher Beams instance ID. Required for `interests` and `users`; ignored for `device`. */
12
- instanceId?: string;
13
- /** Defaults to `interests`. */
9
+ /** Pusher Beams instance ID. */
10
+ instanceId: string;
11
+ /** Beams auth path: `interests` (default) or `users`. */
14
12
  mode?: PusherTransportMode;
15
13
  /** Ask for notification permission (iOS alert/sound/badge, Android 13+ POST_NOTIFICATIONS) during start. Default true. */
16
14
  requestPermission?: boolean;
17
15
  }
18
- /** Remote token endpoint used by the Beams SDK in `users` mode. */
16
+ /** Remote token endpoint used by the Beams SDK when binding a device to a user. */
19
17
  export interface BeamsTokenProvider {
20
18
  /** HTTPS endpoint on your backend that returns `{ token: string }`. */
21
19
  url: string;
@@ -23,17 +21,10 @@ export interface BeamsTokenProvider {
23
21
  queryParams?: Record<string, string>;
24
22
  }
25
23
  /**
26
- * `users` mode auth: either a remote token provider (recommended), or a pre-fetched Beams token string
24
+ * User auth: either a remote token provider (recommended), or a pre-fetched Beams token string
27
25
  * (the b8ne `setUserId(userId, token)` style).
28
26
  */
29
27
  export type BeamsAuth = BeamsTokenProvider | string;
30
- export type DevicePushTokenType = 'fcm' | 'apns';
31
- export interface DevicePushToken {
32
- type: DevicePushTokenType;
33
- /** FCM registration token (Android) or hex-encoded APNs token (iOS). */
34
- token: string;
35
- platform: 'android' | 'ios';
36
- }
37
28
  export interface PusherNotification {
38
29
  title?: string;
39
30
  body?: string;
@@ -42,9 +33,9 @@ export interface PusherNotification {
42
33
  appState: 'foreground' | 'background' | 'opened';
43
34
  }
44
35
  export interface RegisteredEvent {
45
- /** Native device token. In `device` mode this is the token your server sends to. */
36
+ /** Native token the device registered with (FCM on Android, hex APNs on iOS). Beams handles it for you. */
46
37
  deviceToken: string;
47
- type: DevicePushTokenType;
38
+ type: 'fcm' | 'apns';
48
39
  }
49
40
  export interface SubscriptionsChangedEvent {
50
41
  interests: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoPusherPushNotifications.types.d.ts","sourceRoot":"","sources":["../src/ExpoPusherPushNotifications.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpoPusherPushNotifications.types.d.ts","sourceRoot":"","sources":["../src/ExpoPusherPushNotifications.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoPusherPushNotifications.types.js","sourceRoot":"","sources":["../src/ExpoPusherPushNotifications.types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Delivery mode.\n *\n * - `interests`: Pusher Beams interests. Devices subscribe to named interests; server calls Beams `publishToInterests`.\n * - `users`: Pusher Beams Authenticated Users. Device is bound to a user via `setUserId`; server calls Beams `publishToUsers`.\n * - `device`: Raw device-token push. Beams is NOT started. The module obtains the native FCM (Android) /\n * APNs (iOS) device token and hands it to you; your server sends directly to FCM / APNs.\n */\nexport type PusherTransportMode = 'interests' | 'users' | 'device';\n\nexport interface PusherConfig {\n /** Pusher Beams instance ID. Required for `interests` and `users`; ignored for `device`. */\n instanceId?: string;\n /** Defaults to `interests`. */\n mode?: PusherTransportMode;\n /** Ask for notification permission (iOS alert/sound/badge, Android 13+ POST_NOTIFICATIONS) during start. Default true. */\n requestPermission?: boolean;\n}\n\n/** Remote token endpoint used by the Beams SDK in `users` mode. */\nexport interface BeamsTokenProvider {\n /** HTTPS endpoint on your backend that returns `{ token: string }`. */\n url: string;\n headers?: Record<string, string>;\n queryParams?: Record<string, string>;\n}\n\n/**\n * `users` mode auth: either a remote token provider (recommended), or a pre-fetched Beams token string\n * (the b8ne `setUserId(userId, token)` style).\n */\nexport type BeamsAuth = BeamsTokenProvider | string;\n\nexport type DevicePushTokenType = 'fcm' | 'apns';\n\nexport interface DevicePushToken {\n type: DevicePushTokenType;\n /** FCM registration token (Android) or hex-encoded APNs token (iOS). */\n token: string;\n platform: 'android' | 'ios';\n}\n\nexport interface PusherNotification {\n title?: string;\n body?: string;\n data: Record<string, unknown>;\n /** `foreground`: received while running; `background`: received in background; `opened`: user tapped it. */\n appState: 'foreground' | 'background' | 'opened';\n}\n\nexport interface RegisteredEvent {\n /** Native device token. In `device` mode this is the token your server sends to. */\n deviceToken: string;\n type: DevicePushTokenType;\n}\n\nexport interface SubscriptionsChangedEvent {\n interests: string[];\n}\n\nexport interface PusherErrorEvent {\n code: string;\n message: string;\n}\n\nexport type PermissionStatus = 'granted' | 'denied' | 'undetermined' | 'provisional';\n\nexport type AndroidImportance = 'min' | 'low' | 'default' | 'high' | 'max';\n\nexport interface AndroidNotificationChannel {\n id: string;\n name: string;\n description?: string;\n importance?: AndroidImportance;\n /** Bundled sound file name WITHOUT path, e.g. `ding.wav` or `ding`. Must be listed in the plugin's `sounds`. `null` = silent. */\n sound?: string | null;\n vibrate?: boolean;\n lightColor?: string;\n showBadge?: boolean;\n}\n\nexport interface LocalNotification {\n title?: string;\n body?: string;\n data?: Record<string, string>;\n /** Bundled sound file name, e.g. `ding.wav`; `default` for system sound. On Android 8+ the channel's sound wins. */\n sound?: string;\n /** Android channel id. Defaults to the plugin's default channel. */\n channelId?: string;\n /** iOS badge to set with this notification. */\n badge?: number;\n}\n\nexport interface ScheduledNotification extends LocalNotification {\n /** Stable id; reuse to replace. Generated if omitted. */\n id?: string;\n /** Fire after this many seconds (>= 1). */\n seconds: number;\n}\n\nexport type ExpoPusherPushNotificationsModuleEvents = {\n notification: (event: PusherNotification) => void;\n registered: (event: RegisteredEvent) => void;\n subscriptionsChanged: (event: SubscriptionsChangedEvent) => void;\n error: (event: PusherErrorEvent) => void;\n};\n\nexport type PusherEventName = keyof ExpoPusherPushNotificationsModuleEvents;\n"]}
1
+ {"version":3,"file":"ExpoPusherPushNotifications.types.js","sourceRoot":"","sources":["../src/ExpoPusherPushNotifications.types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Which Beams auth path the app uses.\n *\n * - `interests`: devices subscribe to named interests; your server calls Beams `publishToInterests`.\n * - `users`: the device is bound to a user via `setUserId`; your server calls Beams `publishToUsers`.\n */\nexport type PusherTransportMode = 'interests' | 'users';\n\nexport interface PusherConfig {\n /** Pusher Beams instance ID. */\n instanceId: string;\n /** Beams auth path: `interests` (default) or `users`. */\n mode?: PusherTransportMode;\n /** Ask for notification permission (iOS alert/sound/badge, Android 13+ POST_NOTIFICATIONS) during start. Default true. */\n requestPermission?: boolean;\n}\n\n/** Remote token endpoint used by the Beams SDK when binding a device to a user. */\nexport interface BeamsTokenProvider {\n /** HTTPS endpoint on your backend that returns `{ token: string }`. */\n url: string;\n headers?: Record<string, string>;\n queryParams?: Record<string, string>;\n}\n\n/**\n * User auth: either a remote token provider (recommended), or a pre-fetched Beams token string\n * (the b8ne `setUserId(userId, token)` style).\n */\nexport type BeamsAuth = BeamsTokenProvider | string;\n\nexport interface PusherNotification {\n title?: string;\n body?: string;\n data: Record<string, unknown>;\n /** `foreground`: received while running; `background`: received in background; `opened`: user tapped it. */\n appState: 'foreground' | 'background' | 'opened';\n}\n\nexport interface RegisteredEvent {\n /** Native token the device registered with (FCM on Android, hex APNs on iOS). Beams handles it for you. */\n deviceToken: string;\n type: 'fcm' | 'apns';\n}\n\nexport interface SubscriptionsChangedEvent {\n interests: string[];\n}\n\nexport interface PusherErrorEvent {\n code: string;\n message: string;\n}\n\nexport type PermissionStatus = 'granted' | 'denied' | 'undetermined' | 'provisional';\n\nexport type AndroidImportance = 'min' | 'low' | 'default' | 'high' | 'max';\n\nexport interface AndroidNotificationChannel {\n id: string;\n name: string;\n description?: string;\n importance?: AndroidImportance;\n /** Bundled sound file name WITHOUT path, e.g. `ding.wav` or `ding`. Must be listed in the plugin's `sounds`. `null` = silent. */\n sound?: string | null;\n vibrate?: boolean;\n lightColor?: string;\n showBadge?: boolean;\n}\n\nexport interface LocalNotification {\n title?: string;\n body?: string;\n data?: Record<string, string>;\n /** Bundled sound file name, e.g. `ding.wav`; `default` for system sound. On Android 8+ the channel's sound wins. */\n sound?: string;\n /** Android channel id. Defaults to the plugin's default channel. */\n channelId?: string;\n /** iOS badge to set with this notification. */\n badge?: number;\n}\n\nexport interface ScheduledNotification extends LocalNotification {\n /** Stable id; reuse to replace. Generated if omitted. */\n id?: string;\n /** Fire after this many seconds (>= 1). */\n seconds: number;\n}\n\nexport type ExpoPusherPushNotificationsModuleEvents = {\n notification: (event: PusherNotification) => void;\n registered: (event: RegisteredEvent) => void;\n subscriptionsChanged: (event: SubscriptionsChangedEvent) => void;\n error: (event: PusherErrorEvent) => void;\n};\n\nexport type PusherEventName = keyof ExpoPusherPushNotificationsModuleEvents;\n"]}
@@ -1,5 +1,5 @@
1
1
  import { NativeModule } from 'expo';
2
- import type { AndroidNotificationChannel, BeamsTokenProvider, DevicePushToken, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherNotification, ScheduledNotification } from './ExpoPusherPushNotifications.types';
2
+ import type { AndroidNotificationChannel, BeamsTokenProvider, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherNotification, ScheduledNotification } from './ExpoPusherPushNotifications.types';
3
3
  declare class ExpoPusherPushNotificationsNativeModule extends NativeModule<ExpoPusherPushNotificationsModuleEvents> {
4
4
  start(instanceId: string): Promise<void>;
5
5
  addDeviceInterest(interest: string): Promise<void>;
@@ -11,9 +11,6 @@ declare class ExpoPusherPushNotificationsNativeModule extends NativeModule<ExpoP
11
11
  setUserIdWithToken(userId: string, token: string): Promise<void>;
12
12
  clearAllState(): Promise<void>;
13
13
  stop(): Promise<void>;
14
- registerForDeviceToken(): Promise<DevicePushToken>;
15
- getDevicePushToken(): Promise<DevicePushToken | null>;
16
- deleteDevicePushToken(): Promise<void>;
17
14
  requestPermission(): Promise<PermissionStatus>;
18
15
  getPermissionStatus(): Promise<PermissionStatus>;
19
16
  createChannel(channel: AndroidNotificationChannel): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoPusherPushNotificationsModule.d.ts","sourceRoot":"","sources":["../src/ExpoPusherPushNotificationsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,KAAK,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,uCAAuC,EACvC,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,OAAO,uCAAwC,SAAQ,YAAY,CAAC,uCAAuC,CAAC;IACjH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACxC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAClD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACrD,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IACtD,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IACvC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IACrC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3E,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAChE,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErB,sBAAsB,IAAI,OAAO,CAAC,eAAe,CAAC;IAClD,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IACrD,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAEtC,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAC9C,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAEhD,aAAa,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IACjE,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACxC,WAAW,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAEpD,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAChC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3C,wBAAwB,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/D,yBAAyB,CAAC,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IACpE,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACtD,+BAA+B,IAAI,OAAO,CAAC,IAAI,CAAC;IAChD,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IACxC,sBAAsB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;CAC7D;;AAED,wBAA2G"}
1
+ {"version":3,"file":"ExpoPusherPushNotificationsModule.d.ts","sourceRoot":"","sources":["../src/ExpoPusherPushNotificationsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,KAAK,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,uCAAuC,EACvC,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,OAAO,uCAAwC,SAAQ,YAAY,CAAC,uCAAuC,CAAC;IACjH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACxC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAClD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACrD,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IACtD,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IACvC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IACrC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3E,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAChE,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErB,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAC9C,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAEhD,aAAa,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IACjE,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACxC,WAAW,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAEpD,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAChC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3C,wBAAwB,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/D,yBAAyB,CAAC,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IACpE,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACtD,+BAA+B,IAAI,OAAO,CAAC,IAAI,CAAC;IAChD,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IACxC,sBAAsB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;CAC7D;;AAED,wBAA2G"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoPusherPushNotificationsModule.js","sourceRoot":"","sources":["../src/ExpoPusherPushNotificationsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AA+CzD,eAAe,mBAAmB,CAA0C,6BAA6B,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from 'expo';\n\nimport type {\n AndroidNotificationChannel,\n BeamsTokenProvider,\n DevicePushToken,\n ExpoPusherPushNotificationsModuleEvents,\n LocalNotification,\n PermissionStatus,\n PusherNotification,\n ScheduledNotification,\n} from './ExpoPusherPushNotifications.types';\n\ndeclare class ExpoPusherPushNotificationsNativeModule extends NativeModule<ExpoPusherPushNotificationsModuleEvents> {\n start(instanceId: string): Promise<void>;\n addDeviceInterest(interest: string): Promise<void>;\n removeDeviceInterest(interest: string): Promise<void>;\n setDeviceInterests(interests: string[]): Promise<void>;\n getDeviceInterests(): Promise<string[]>;\n clearDeviceInterests(): Promise<void>;\n setUserId(userId: string, tokenProvider: BeamsTokenProvider): Promise<void>;\n setUserIdWithToken(userId: string, token: string): Promise<void>;\n clearAllState(): Promise<void>;\n stop(): Promise<void>;\n // device-token mode\n registerForDeviceToken(): Promise<DevicePushToken>;\n getDevicePushToken(): Promise<DevicePushToken | null>;\n deleteDevicePushToken(): Promise<void>;\n // permissions\n requestPermission(): Promise<PermissionStatus>;\n getPermissionStatus(): Promise<PermissionStatus>;\n // channels (Android; no-ops on iOS)\n createChannel(channel: AndroidNotificationChannel): Promise<void>;\n deleteChannel(id: string): Promise<void>;\n getChannels(): Promise<AndroidNotificationChannel[]>;\n // badge\n getBadgeCount(): Promise<number>;\n setBadgeCount(count: number): Promise<void>;\n // local\n presentLocalNotification(n: LocalNotification): Promise<string>;\n scheduleLocalNotification(n: ScheduledNotification): Promise<string>;\n cancelScheduledNotification(id: string): Promise<void>;\n cancelAllScheduledNotifications(): Promise<void>;\n dismissAllNotifications(): Promise<void>;\n getInitialNotification(): Promise<PusherNotification | null>;\n}\n\nexport default requireNativeModule<ExpoPusherPushNotificationsNativeModule>('ExpoPusherPushNotifications');\n"]}
1
+ {"version":3,"file":"ExpoPusherPushNotificationsModule.js","sourceRoot":"","sources":["../src/ExpoPusherPushNotificationsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AA0CzD,eAAe,mBAAmB,CAA0C,6BAA6B,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from 'expo';\n\nimport type {\n AndroidNotificationChannel,\n BeamsTokenProvider,\n ExpoPusherPushNotificationsModuleEvents,\n LocalNotification,\n PermissionStatus,\n PusherNotification,\n ScheduledNotification,\n} from './ExpoPusherPushNotifications.types';\n\ndeclare class ExpoPusherPushNotificationsNativeModule extends NativeModule<ExpoPusherPushNotificationsModuleEvents> {\n start(instanceId: string): Promise<void>;\n addDeviceInterest(interest: string): Promise<void>;\n removeDeviceInterest(interest: string): Promise<void>;\n setDeviceInterests(interests: string[]): Promise<void>;\n getDeviceInterests(): Promise<string[]>;\n clearDeviceInterests(): Promise<void>;\n setUserId(userId: string, tokenProvider: BeamsTokenProvider): Promise<void>;\n setUserIdWithToken(userId: string, token: string): Promise<void>;\n clearAllState(): Promise<void>;\n stop(): Promise<void>;\n // permissions\n requestPermission(): Promise<PermissionStatus>;\n getPermissionStatus(): Promise<PermissionStatus>;\n // channels (Android; no-ops on iOS)\n createChannel(channel: AndroidNotificationChannel): Promise<void>;\n deleteChannel(id: string): Promise<void>;\n getChannels(): Promise<AndroidNotificationChannel[]>;\n // badge\n getBadgeCount(): Promise<number>;\n setBadgeCount(count: number): Promise<void>;\n // local\n presentLocalNotification(n: LocalNotification): Promise<string>;\n scheduleLocalNotification(n: ScheduledNotification): Promise<string>;\n cancelScheduledNotification(id: string): Promise<void>;\n cancelAllScheduledNotifications(): Promise<void>;\n dismissAllNotifications(): Promise<void>;\n getInitialNotification(): Promise<PusherNotification | null>;\n}\n\nexport default requireNativeModule<ExpoPusherPushNotificationsNativeModule>('ExpoPusherPushNotifications');\n"]}
package/build/index.d.ts CHANGED
@@ -1,13 +1,8 @@
1
1
  import type { EventSubscription } from 'expo-modules-core';
2
- import type { AndroidNotificationChannel, BeamsAuth, DevicePushToken, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherConfig, PusherEventName, PusherNotification, PusherTransportMode, ScheduledNotification } from './ExpoPusherPushNotifications.types';
2
+ import type { AndroidNotificationChannel, BeamsAuth, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherConfig, PusherEventName, PusherNotification, PusherTransportMode, ScheduledNotification } from './ExpoPusherPushNotifications.types';
3
3
  export * from './ExpoPusherPushNotifications.types';
4
- /**
5
- * Starts the module in one of three modes.
6
- * - `interests` / `users`: starts the Pusher Beams SDK (requires `instanceId`).
7
- * - `device`: does NOT start Beams; registers with FCM/APNs and resolves the raw device token.
8
- * Resolves with the device token in `device` mode, otherwise `null`.
9
- */
10
- export declare function start(config: PusherConfig): Promise<DevicePushToken | null>;
4
+ /** Starts Pusher Beams. */
5
+ export declare function start(config: PusherConfig): Promise<void>;
11
6
  export declare function getMode(): PusherTransportMode;
12
7
  export declare function subscribe(interest: string): Promise<void>;
13
8
  export declare function unsubscribe(interest: string): Promise<void>;
@@ -16,12 +11,6 @@ export declare function getSubscriptions(): Promise<string[]>;
16
11
  export declare function clearSubscriptions(): Promise<void>;
17
12
  /** Pass a token provider `{ url, headers?, queryParams? }` or a pre-fetched Beams token string. */
18
13
  export declare function setUserId(userId: string, auth: BeamsAuth): Promise<void>;
19
- /** Registers with FCM/APNs (if needed) and returns the native token. Works in any mode. */
20
- export declare function registerForDeviceToken(): Promise<DevicePushToken>;
21
- /** Last known native token, or null if not registered yet. */
22
- export declare function getDevicePushToken(): Promise<DevicePushToken | null>;
23
- /** Android: deletes the FCM token (a new one is issued on next register). iOS: unregisters from APNs. */
24
- export declare function deleteDevicePushToken(): Promise<void>;
25
14
  export declare function requestPermission(): Promise<PermissionStatus>;
26
15
  export declare function getPermissionStatus(): Promise<PermissionStatus>;
27
16
  export declare function createChannel(channel: AndroidNotificationChannel): Promise<void>;
@@ -39,20 +28,20 @@ export declare function dismissAllNotifications(): Promise<void>;
39
28
  export declare function getInitialNotification(): Promise<PusherNotification | null>;
40
29
  export declare function clearAllState(): Promise<void>;
41
30
  export declare function stop(): Promise<void>;
42
- /** Adds an event listener. Events fire in all modes. */
31
+ /** Adds an event listener. Events fire for interests and users alike. */
43
32
  export declare function addListener<E extends PusherEventName>(eventName: E, listener: ExpoPusherPushNotificationsModuleEvents[E]): EventSubscription;
44
33
  /** Alias for `addListener` (old package's `on()`). */
45
34
  export declare const on: typeof addListener;
46
35
  /**
47
- * Mode 1 — Pusher Beams **interests** (topic broadcast).
36
+ * Pusher Beams **interests** (topic broadcast).
48
37
  * Use when many devices should get the same push: "news", "order-42", "team-7".
49
38
  * Server: `beams.publishToInterests([...], payload)`.
50
39
  */
51
40
  export declare const Interests: {
52
- /** Start Beams in interests mode. */
41
+ /** Start Beams. */
53
42
  readonly start: (instanceId: string, opts?: {
54
43
  requestPermission?: boolean;
55
- }) => Promise<undefined>;
44
+ }) => Promise<void>;
56
45
  readonly subscribe: typeof subscribe;
57
46
  readonly unsubscribe: typeof unsubscribe;
58
47
  readonly set: typeof setSubscriptions;
@@ -63,43 +52,27 @@ export declare const Interests: {
63
52
  readonly stop: typeof stop;
64
53
  };
65
54
  /**
66
- * Mode 2 — Pusher Beams **authenticated users** (push to a person, across all their devices).
55
+ * Pusher Beams **authenticated users** (push to a person, across all their devices).
67
56
  * Use when your backend thinks in user ids: "send to user-123".
68
57
  * Server: `beams.publishToUsers(['user-123'], payload)` + a token endpoint (`beams.generateToken`).
69
58
  */
70
59
  export declare const Users: {
71
- /** Start Beams in users mode. Call `login()` after your own sign-in. */
60
+ /** Start Beams. Call `login()` after your own sign-in. */
72
61
  readonly start: (instanceId: string, opts?: {
73
62
  requestPermission?: boolean;
74
- }) => Promise<undefined>;
63
+ }) => Promise<void>;
75
64
  /** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */
76
65
  readonly login: typeof setUserId;
77
66
  /** Unbind the device (call on sign-out). */
78
67
  readonly logout: typeof clearAllState;
79
68
  readonly stop: typeof stop;
80
69
  };
81
- /**
82
- * Mode 3 — **direct FCM / APNs** (no Pusher at all).
83
- * Use when your server already talks to FCM HTTP v1 / APNs, or you use another provider.
84
- * You get the raw native token; send it to your backend and keep it fresh via the `registered` event.
85
- */
86
- export declare const DeviceToken: {
87
- /** Register with FCM/APNs and resolve the native token. */
88
- readonly start: (opts?: {
89
- requestPermission?: boolean;
90
- }) => Promise<DevicePushToken>;
91
- readonly get: typeof getDevicePushToken;
92
- /** Fires whenever the token is issued or rotated. */
93
- readonly onChange: (cb: (token: DevicePushToken) => void) => EventSubscription;
94
- /** Delete the token (call on sign-out). */
95
- readonly delete: typeof deleteDevicePushToken;
96
- };
97
70
  declare const _default: {
98
71
  readonly Interests: {
99
- /** Start Beams in interests mode. */
72
+ /** Start Beams. */
100
73
  readonly start: (instanceId: string, opts?: {
101
74
  requestPermission?: boolean;
102
- }) => Promise<undefined>;
75
+ }) => Promise<void>;
103
76
  readonly subscribe: typeof subscribe;
104
77
  readonly unsubscribe: typeof unsubscribe;
105
78
  readonly set: typeof setSubscriptions;
@@ -110,27 +83,16 @@ declare const _default: {
110
83
  readonly stop: typeof stop;
111
84
  };
112
85
  readonly Users: {
113
- /** Start Beams in users mode. Call `login()` after your own sign-in. */
86
+ /** Start Beams. Call `login()` after your own sign-in. */
114
87
  readonly start: (instanceId: string, opts?: {
115
88
  requestPermission?: boolean;
116
- }) => Promise<undefined>;
89
+ }) => Promise<void>;
117
90
  /** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */
118
91
  readonly login: typeof setUserId;
119
92
  /** Unbind the device (call on sign-out). */
120
93
  readonly logout: typeof clearAllState;
121
94
  readonly stop: typeof stop;
122
95
  };
123
- readonly DeviceToken: {
124
- /** Register with FCM/APNs and resolve the native token. */
125
- readonly start: (opts?: {
126
- requestPermission?: boolean;
127
- }) => Promise<DevicePushToken>;
128
- readonly get: typeof getDevicePushToken;
129
- /** Fires whenever the token is issued or rotated. */
130
- readonly onChange: (cb: (token: DevicePushToken) => void) => EventSubscription;
131
- /** Delete the token (call on sign-out). */
132
- readonly delete: typeof deleteDevicePushToken;
133
- };
134
96
  readonly start: typeof start;
135
97
  readonly getMode: typeof getMode;
136
98
  readonly subscribe: typeof subscribe;
@@ -139,9 +101,6 @@ declare const _default: {
139
101
  readonly getSubscriptions: typeof getSubscriptions;
140
102
  readonly clearSubscriptions: typeof clearSubscriptions;
141
103
  readonly setUserId: typeof setUserId;
142
- readonly registerForDeviceToken: typeof registerForDeviceToken;
143
- readonly getDevicePushToken: typeof getDevicePushToken;
144
- readonly deleteDevicePushToken: typeof deleteDevicePushToken;
145
104
  readonly requestPermission: typeof requestPermission;
146
105
  readonly getPermissionStatus: typeof getPermissionStatus;
147
106
  readonly createChannel: typeof createChannel;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -6,36 +6,21 @@ const PREFIX = 'expo-pusher-push-notifications';
6
6
  function assertBeams(fn) {
7
7
  if (!started)
8
8
  throw new Error(`${PREFIX}: call start() before ${fn}().`);
9
- if (currentMode === 'device') {
10
- throw new Error(`${PREFIX}: ${fn}() is a Pusher Beams API and is unavailable in 'device' mode.`);
11
- }
12
9
  }
13
- /**
14
- * Starts the module in one of three modes.
15
- * - `interests` / `users`: starts the Pusher Beams SDK (requires `instanceId`).
16
- * - `device`: does NOT start Beams; registers with FCM/APNs and resolves the raw device token.
17
- * Resolves with the device token in `device` mode, otherwise `null`.
18
- */
10
+ /** Starts Pusher Beams. */
19
11
  export async function start(config) {
20
- const mode = config.mode ?? 'interests';
12
+ if (!config.instanceId)
13
+ throw new Error(`${PREFIX}: instanceId is required.`);
21
14
  if (config.requestPermission !== false)
22
15
  await Native.requestPermission();
23
- currentMode = mode;
24
- if (mode === 'device') {
25
- const token = await Native.registerForDeviceToken();
26
- started = true;
27
- return token;
28
- }
29
- if (!config.instanceId)
30
- throw new Error(`${PREFIX}: instanceId is required for '${mode}' mode.`);
16
+ currentMode = config.mode ?? 'interests';
31
17
  await Native.start(config.instanceId);
32
18
  started = true;
33
- return null;
34
19
  }
35
20
  export function getMode() {
36
21
  return currentMode;
37
22
  }
38
- // ---- Mode 1: Beams interests ----
23
+ // ---- Interests (topics) ----
39
24
  export async function subscribe(interest) {
40
25
  assertBeams('subscribe');
41
26
  await Native.addDeviceInterest(interest);
@@ -56,7 +41,7 @@ export async function clearSubscriptions() {
56
41
  assertBeams('clearSubscriptions');
57
42
  await Native.clearDeviceInterests();
58
43
  }
59
- // ---- Mode 2: Beams authenticated users ----
44
+ // ---- Bind a device to a user ----
60
45
  /** Pass a token provider `{ url, headers?, queryParams? }` or a pre-fetched Beams token string. */
61
46
  export async function setUserId(userId, auth) {
62
47
  assertBeams('setUserId');
@@ -65,19 +50,6 @@ export async function setUserId(userId, auth) {
65
50
  else
66
51
  await Native.setUserId(userId, auth);
67
52
  }
68
- // ---- Mode 3: raw device token (direct FCM / APNs) ----
69
- /** Registers with FCM/APNs (if needed) and returns the native token. Works in any mode. */
70
- export async function registerForDeviceToken() {
71
- return Native.registerForDeviceToken();
72
- }
73
- /** Last known native token, or null if not registered yet. */
74
- export async function getDevicePushToken() {
75
- return Native.getDevicePushToken();
76
- }
77
- /** Android: deletes the FCM token (a new one is issued on next register). iOS: unregisters from APNs. */
78
- export async function deleteDevicePushToken() {
79
- await Native.deleteDevicePushToken();
80
- }
81
53
  // ---- Permissions ----
82
54
  export function requestPermission() {
83
55
  return Native.requestPermission();
@@ -131,35 +103,30 @@ export function getInitialNotification() {
131
103
  }
132
104
  // ---- Common ----
133
105
  export async function clearAllState() {
134
- if (currentMode !== 'device')
135
- await Native.clearAllState();
106
+ await Native.clearAllState();
136
107
  }
137
108
  export async function stop() {
138
- if (currentMode === 'device')
139
- await Native.deleteDevicePushToken();
140
- else
141
- await Native.stop();
109
+ await Native.stop();
142
110
  started = false;
143
111
  }
144
- /** Adds an event listener. Events fire in all modes. */
112
+ /** Adds an event listener. Events fire for interests and users alike. */
145
113
  export function addListener(eventName, listener) {
146
114
  return Native.addListener(eventName, listener);
147
115
  }
148
116
  /** Alias for `addListener` (old package's `on()`). */
149
117
  export const on = addListener;
150
118
  // ---------------------------------------------------------------------------
151
- // Mode-scoped API. Pick ONE of these three and ignore the other two.
152
- // Everything below (sounds, channels, badges, local notifications, events)
153
- // is shared and works in every mode.
119
+ // Convenience objects. Use either or both; everything else (sounds,
120
+ // channels, badges, local notifications, events) works the same either way.
154
121
  // ---------------------------------------------------------------------------
155
122
  /**
156
- * Mode 1 — Pusher Beams **interests** (topic broadcast).
123
+ * Pusher Beams **interests** (topic broadcast).
157
124
  * Use when many devices should get the same push: "news", "order-42", "team-7".
158
125
  * Server: `beams.publishToInterests([...], payload)`.
159
126
  */
160
127
  export const Interests = {
161
- /** Start Beams in interests mode. */
162
- start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'interests' }).then(() => undefined),
128
+ /** Start Beams. */
129
+ start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'interests' }),
163
130
  subscribe,
164
131
  unsubscribe,
165
132
  set: setSubscriptions,
@@ -170,39 +137,24 @@ export const Interests = {
170
137
  stop,
171
138
  };
172
139
  /**
173
- * Mode 2 — Pusher Beams **authenticated users** (push to a person, across all their devices).
140
+ * Pusher Beams **authenticated users** (push to a person, across all their devices).
174
141
  * Use when your backend thinks in user ids: "send to user-123".
175
142
  * Server: `beams.publishToUsers(['user-123'], payload)` + a token endpoint (`beams.generateToken`).
176
143
  */
177
144
  export const Users = {
178
- /** Start Beams in users mode. Call `login()` after your own sign-in. */
179
- start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'users' }).then(() => undefined),
145
+ /** Start Beams. Call `login()` after your own sign-in. */
146
+ start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'users' }),
180
147
  /** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */
181
148
  login: setUserId,
182
149
  /** Unbind the device (call on sign-out). */
183
150
  logout: clearAllState,
184
151
  stop,
185
152
  };
186
- /**
187
- * Mode 3 — **direct FCM / APNs** (no Pusher at all).
188
- * Use when your server already talks to FCM HTTP v1 / APNs, or you use another provider.
189
- * You get the raw native token; send it to your backend and keep it fresh via the `registered` event.
190
- */
191
- export const DeviceToken = {
192
- /** Register with FCM/APNs and resolve the native token. */
193
- start: async (opts = {}) => (await start({ ...opts, mode: 'device' })),
194
- get: getDevicePushToken,
195
- /** Fires whenever the token is issued or rotated. */
196
- onChange: (cb) => addListener('registered', ({ deviceToken, type }) => cb({ token: deviceToken, type, platform: type === 'fcm' ? 'android' : 'ios' })),
197
- /** Delete the token (call on sign-out). */
198
- delete: deleteDevicePushToken,
199
- };
200
153
  export default {
201
- Interests, Users, DeviceToken,
154
+ Interests, Users,
202
155
  start, getMode,
203
156
  subscribe, unsubscribe, setSubscriptions, getSubscriptions, clearSubscriptions,
204
157
  setUserId,
205
- registerForDeviceToken, getDevicePushToken, deleteDevicePushToken,
206
158
  requestPermission, getPermissionStatus,
207
159
  createChannel, deleteChannel, getChannels,
208
160
  getBadgeCount, setBadgeCount, incrementBadgeCount,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EventSubscription } from 'expo-modules-core';\n\nimport Native from './ExpoPusherPushNotificationsModule';\nimport type {\n AndroidNotificationChannel,\n BeamsAuth,\n DevicePushToken,\n ExpoPusherPushNotificationsModuleEvents,\n LocalNotification,\n PermissionStatus,\n PusherConfig,\n PusherEventName,\n PusherNotification,\n PusherTransportMode,\n ScheduledNotification,\n} from './ExpoPusherPushNotifications.types';\n\nexport * from './ExpoPusherPushNotifications.types';\n\nlet currentMode: PusherTransportMode = 'interests';\nlet started = false;\n\nconst PREFIX = 'expo-pusher-push-notifications';\n\nfunction assertBeams(fn: string): void {\n if (!started) throw new Error(`${PREFIX}: call start() before ${fn}().`);\n if (currentMode === 'device') {\n throw new Error(`${PREFIX}: ${fn}() is a Pusher Beams API and is unavailable in 'device' mode.`);\n }\n}\n\n/**\n * Starts the module in one of three modes.\n * - `interests` / `users`: starts the Pusher Beams SDK (requires `instanceId`).\n * - `device`: does NOT start Beams; registers with FCM/APNs and resolves the raw device token.\n * Resolves with the device token in `device` mode, otherwise `null`.\n */\nexport async function start(config: PusherConfig): Promise<DevicePushToken | null> {\n const mode = config.mode ?? 'interests';\n if (config.requestPermission !== false) await Native.requestPermission();\n currentMode = mode;\n if (mode === 'device') {\n const token = await Native.registerForDeviceToken();\n started = true;\n return token;\n }\n if (!config.instanceId) throw new Error(`${PREFIX}: instanceId is required for '${mode}' mode.`);\n await Native.start(config.instanceId);\n started = true;\n return null;\n}\n\nexport function getMode(): PusherTransportMode {\n return currentMode;\n}\n\n// ---- Mode 1: Beams interests ----\nexport async function subscribe(interest: string): Promise<void> {\n assertBeams('subscribe');\n await Native.addDeviceInterest(interest);\n}\nexport async function unsubscribe(interest: string): Promise<void> {\n assertBeams('unsubscribe');\n await Native.removeDeviceInterest(interest);\n}\nexport async function setSubscriptions(interests: string[]): Promise<void> {\n assertBeams('setSubscriptions');\n await Native.setDeviceInterests(interests);\n}\nexport async function getSubscriptions(): Promise<string[]> {\n assertBeams('getSubscriptions');\n return Native.getDeviceInterests();\n}\nexport async function clearSubscriptions(): Promise<void> {\n assertBeams('clearSubscriptions');\n await Native.clearDeviceInterests();\n}\n\n// ---- Mode 2: Beams authenticated users ----\n/** Pass a token provider `{ url, headers?, queryParams? }` or a pre-fetched Beams token string. */\nexport async function setUserId(userId: string, auth: BeamsAuth): Promise<void> {\n assertBeams('setUserId');\n if (typeof auth === 'string') await Native.setUserIdWithToken(userId, auth);\n else await Native.setUserId(userId, auth);\n}\n\n// ---- Mode 3: raw device token (direct FCM / APNs) ----\n/** Registers with FCM/APNs (if needed) and returns the native token. Works in any mode. */\nexport async function registerForDeviceToken(): Promise<DevicePushToken> {\n return Native.registerForDeviceToken();\n}\n/** Last known native token, or null if not registered yet. */\nexport async function getDevicePushToken(): Promise<DevicePushToken | null> {\n return Native.getDevicePushToken();\n}\n/** Android: deletes the FCM token (a new one is issued on next register). iOS: unregisters from APNs. */\nexport async function deleteDevicePushToken(): Promise<void> {\n await Native.deleteDevicePushToken();\n}\n\n// ---- Permissions ----\nexport function requestPermission(): Promise<PermissionStatus> {\n return Native.requestPermission();\n}\nexport function getPermissionStatus(): Promise<PermissionStatus> {\n return Native.getPermissionStatus();\n}\n\n// ---- Android notification channels (no-ops on iOS) ----\nexport function createChannel(channel: AndroidNotificationChannel): Promise<void> {\n return Native.createChannel(channel);\n}\nexport function deleteChannel(id: string): Promise<void> {\n return Native.deleteChannel(id);\n}\nexport function getChannels(): Promise<AndroidNotificationChannel[]> {\n return Native.getChannels();\n}\n\n// ---- Badge ----\nexport function getBadgeCount(): Promise<number> {\n return Native.getBadgeCount();\n}\nexport function setBadgeCount(count: number): Promise<void> {\n return Native.setBadgeCount(Math.max(0, Math.floor(count)));\n}\nexport async function incrementBadgeCount(by = 1): Promise<number> {\n const next = (await Native.getBadgeCount()) + by;\n await setBadgeCount(next);\n return Math.max(0, next);\n}\n\n// ---- Local notifications ----\nexport function presentLocalNotification(n: LocalNotification): Promise<string> {\n return Native.presentLocalNotification(n);\n}\nexport function scheduleLocalNotification(n: ScheduledNotification): Promise<string> {\n if (!(n.seconds >= 1)) throw new Error(`${PREFIX}: seconds must be >= 1.`);\n return Native.scheduleLocalNotification(n);\n}\nexport function cancelScheduledNotification(id: string): Promise<void> {\n return Native.cancelScheduledNotification(id);\n}\nexport function cancelAllScheduledNotifications(): Promise<void> {\n return Native.cancelAllScheduledNotifications();\n}\nexport function dismissAllNotifications(): Promise<void> {\n return Native.dismissAllNotifications();\n}\n/** The notification whose tap launched the app (cold start), if any. */\nexport function getInitialNotification(): Promise<PusherNotification | null> {\n return Native.getInitialNotification();\n}\n\n// ---- Common ----\nexport async function clearAllState(): Promise<void> {\n if (currentMode !== 'device') await Native.clearAllState();\n}\nexport async function stop(): Promise<void> {\n if (currentMode === 'device') await Native.deleteDevicePushToken();\n else await Native.stop();\n started = false;\n}\n\n/** Adds an event listener. Events fire in all modes. */\nexport function addListener<E extends PusherEventName>(\n eventName: E,\n listener: ExpoPusherPushNotificationsModuleEvents[E]\n): EventSubscription {\n return Native.addListener(eventName, listener);\n}\n/** Alias for `addListener` (old package's `on()`). */\nexport const on = addListener;\n\n// ---------------------------------------------------------------------------\n// Mode-scoped API. Pick ONE of these three and ignore the other two.\n// Everything below (sounds, channels, badges, local notifications, events)\n// is shared and works in every mode.\n// ---------------------------------------------------------------------------\n\n/**\n * Mode 1 — Pusher Beams **interests** (topic broadcast).\n * Use when many devices should get the same push: \"news\", \"order-42\", \"team-7\".\n * Server: `beams.publishToInterests([...], payload)`.\n */\nexport const Interests = {\n /** Start Beams in interests mode. */\n start: (instanceId: string, opts: { requestPermission?: boolean } = {}) =>\n start({ ...opts, instanceId, mode: 'interests' }).then(() => undefined),\n subscribe,\n unsubscribe,\n set: setSubscriptions,\n get: getSubscriptions,\n clear: clearSubscriptions,\n /** Forget everything (call on logout). */\n reset: clearAllState,\n stop,\n} as const;\n\n/**\n * Mode 2 — Pusher Beams **authenticated users** (push to a person, across all their devices).\n * Use when your backend thinks in user ids: \"send to user-123\".\n * Server: `beams.publishToUsers(['user-123'], payload)` + a token endpoint (`beams.generateToken`).\n */\nexport const Users = {\n /** Start Beams in users mode. Call `login()` after your own sign-in. */\n start: (instanceId: string, opts: { requestPermission?: boolean } = {}) =>\n start({ ...opts, instanceId, mode: 'users' }).then(() => undefined),\n /** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */\n login: setUserId,\n /** Unbind the device (call on sign-out). */\n logout: clearAllState,\n stop,\n} as const;\n\n/**\n * Mode 3 — **direct FCM / APNs** (no Pusher at all).\n * Use when your server already talks to FCM HTTP v1 / APNs, or you use another provider.\n * You get the raw native token; send it to your backend and keep it fresh via the `registered` event.\n */\nexport const DeviceToken = {\n /** Register with FCM/APNs and resolve the native token. */\n start: async (opts: { requestPermission?: boolean } = {}): Promise<DevicePushToken> =>\n (await start({ ...opts, mode: 'device' })) as DevicePushToken,\n get: getDevicePushToken,\n /** Fires whenever the token is issued or rotated. */\n onChange: (cb: (token: DevicePushToken) => void): EventSubscription =>\n addListener('registered', ({ deviceToken, type }) =>\n cb({ token: deviceToken, type, platform: type === 'fcm' ? 'android' : 'ios' })\n ),\n /** Delete the token (call on sign-out). */\n delete: deleteDevicePushToken,\n} as const;\n\nexport default {\n Interests, Users, DeviceToken,\n start, getMode,\n subscribe, unsubscribe, setSubscriptions, getSubscriptions, clearSubscriptions,\n setUserId,\n registerForDeviceToken, getDevicePushToken, deleteDevicePushToken,\n requestPermission, getPermissionStatus,\n createChannel, deleteChannel, getChannels,\n getBadgeCount, setBadgeCount, incrementBadgeCount,\n presentLocalNotification, scheduleLocalNotification, cancelScheduledNotification,\n cancelAllScheduledNotifications, dismissAllNotifications, getInitialNotification,\n clearAllState, stop, addListener, on,\n} as const;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EventSubscription } from 'expo-modules-core';\n\nimport Native from './ExpoPusherPushNotificationsModule';\nimport type {\n AndroidNotificationChannel,\n BeamsAuth,\n ExpoPusherPushNotificationsModuleEvents,\n LocalNotification,\n PermissionStatus,\n PusherConfig,\n PusherEventName,\n PusherNotification,\n PusherTransportMode,\n ScheduledNotification,\n} from './ExpoPusherPushNotifications.types';\n\nexport * from './ExpoPusherPushNotifications.types';\n\nlet currentMode: PusherTransportMode = 'interests';\nlet started = false;\n\nconst PREFIX = 'expo-pusher-push-notifications';\n\nfunction assertBeams(fn: string): void {\n if (!started) throw new Error(`${PREFIX}: call start() before ${fn}().`);\n}\n\n/** Starts Pusher Beams. */\nexport async function start(config: PusherConfig): Promise<void> {\n if (!config.instanceId) throw new Error(`${PREFIX}: instanceId is required.`);\n if (config.requestPermission !== false) await Native.requestPermission();\n currentMode = config.mode ?? 'interests';\n await Native.start(config.instanceId);\n started = true;\n}\n\nexport function getMode(): PusherTransportMode {\n return currentMode;\n}\n\n// ---- Interests (topics) ----\nexport async function subscribe(interest: string): Promise<void> {\n assertBeams('subscribe');\n await Native.addDeviceInterest(interest);\n}\nexport async function unsubscribe(interest: string): Promise<void> {\n assertBeams('unsubscribe');\n await Native.removeDeviceInterest(interest);\n}\nexport async function setSubscriptions(interests: string[]): Promise<void> {\n assertBeams('setSubscriptions');\n await Native.setDeviceInterests(interests);\n}\nexport async function getSubscriptions(): Promise<string[]> {\n assertBeams('getSubscriptions');\n return Native.getDeviceInterests();\n}\nexport async function clearSubscriptions(): Promise<void> {\n assertBeams('clearSubscriptions');\n await Native.clearDeviceInterests();\n}\n\n// ---- Bind a device to a user ----\n/** Pass a token provider `{ url, headers?, queryParams? }` or a pre-fetched Beams token string. */\nexport async function setUserId(userId: string, auth: BeamsAuth): Promise<void> {\n assertBeams('setUserId');\n if (typeof auth === 'string') await Native.setUserIdWithToken(userId, auth);\n else await Native.setUserId(userId, auth);\n}\n\n// ---- Permissions ----\nexport function requestPermission(): Promise<PermissionStatus> {\n return Native.requestPermission();\n}\nexport function getPermissionStatus(): Promise<PermissionStatus> {\n return Native.getPermissionStatus();\n}\n\n// ---- Android notification channels (no-ops on iOS) ----\nexport function createChannel(channel: AndroidNotificationChannel): Promise<void> {\n return Native.createChannel(channel);\n}\nexport function deleteChannel(id: string): Promise<void> {\n return Native.deleteChannel(id);\n}\nexport function getChannels(): Promise<AndroidNotificationChannel[]> {\n return Native.getChannels();\n}\n\n// ---- Badge ----\nexport function getBadgeCount(): Promise<number> {\n return Native.getBadgeCount();\n}\nexport function setBadgeCount(count: number): Promise<void> {\n return Native.setBadgeCount(Math.max(0, Math.floor(count)));\n}\nexport async function incrementBadgeCount(by = 1): Promise<number> {\n const next = (await Native.getBadgeCount()) + by;\n await setBadgeCount(next);\n return Math.max(0, next);\n}\n\n// ---- Local notifications ----\nexport function presentLocalNotification(n: LocalNotification): Promise<string> {\n return Native.presentLocalNotification(n);\n}\nexport function scheduleLocalNotification(n: ScheduledNotification): Promise<string> {\n if (!(n.seconds >= 1)) throw new Error(`${PREFIX}: seconds must be >= 1.`);\n return Native.scheduleLocalNotification(n);\n}\nexport function cancelScheduledNotification(id: string): Promise<void> {\n return Native.cancelScheduledNotification(id);\n}\nexport function cancelAllScheduledNotifications(): Promise<void> {\n return Native.cancelAllScheduledNotifications();\n}\nexport function dismissAllNotifications(): Promise<void> {\n return Native.dismissAllNotifications();\n}\n/** The notification whose tap launched the app (cold start), if any. */\nexport function getInitialNotification(): Promise<PusherNotification | null> {\n return Native.getInitialNotification();\n}\n\n// ---- Common ----\nexport async function clearAllState(): Promise<void> {\n await Native.clearAllState();\n}\nexport async function stop(): Promise<void> {\n await Native.stop();\n started = false;\n}\n\n/** Adds an event listener. Events fire for interests and users alike. */\nexport function addListener<E extends PusherEventName>(\n eventName: E,\n listener: ExpoPusherPushNotificationsModuleEvents[E]\n): EventSubscription {\n return Native.addListener(eventName, listener);\n}\n/** Alias for `addListener` (old package's `on()`). */\nexport const on = addListener;\n\n// ---------------------------------------------------------------------------\n// Convenience objects. Use either or both; everything else (sounds,\n// channels, badges, local notifications, events) works the same either way.\n// ---------------------------------------------------------------------------\n\n/**\n * Pusher Beams **interests** (topic broadcast).\n * Use when many devices should get the same push: \"news\", \"order-42\", \"team-7\".\n * Server: `beams.publishToInterests([...], payload)`.\n */\nexport const Interests = {\n /** Start Beams. */\n start: (instanceId: string, opts: { requestPermission?: boolean } = {}) =>\n start({ ...opts, instanceId, mode: 'interests' }),\n subscribe,\n unsubscribe,\n set: setSubscriptions,\n get: getSubscriptions,\n clear: clearSubscriptions,\n /** Forget everything (call on logout). */\n reset: clearAllState,\n stop,\n} as const;\n\n/**\n * Pusher Beams **authenticated users** (push to a person, across all their devices).\n * Use when your backend thinks in user ids: \"send to user-123\".\n * Server: `beams.publishToUsers(['user-123'], payload)` + a token endpoint (`beams.generateToken`).\n */\nexport const Users = {\n /** Start Beams. Call `login()` after your own sign-in. */\n start: (instanceId: string, opts: { requestPermission?: boolean } = {}) =>\n start({ ...opts, instanceId, mode: 'users' }),\n /** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */\n login: setUserId,\n /** Unbind the device (call on sign-out). */\n logout: clearAllState,\n stop,\n} as const;\n\nexport default {\n Interests, Users,\n start, getMode,\n subscribe, unsubscribe, setSubscriptions, getSubscriptions, clearSubscriptions,\n setUserId,\n requestPermission, getPermissionStatus,\n createChannel, deleteChannel, getChannels,\n getBadgeCount, setBadgeCount, incrementBadgeCount,\n presentLocalNotification, scheduleLocalNotification, cancelScheduledNotification,\n cancelAllScheduledNotifications, dismissAllNotifications, getInitialNotification,\n clearAllState, stop, addListener, on,\n} as const;\n"]}
package/docs/api.md CHANGED
@@ -1,21 +1,20 @@
1
1
  # Full API
2
2
 
3
- The mode objects (`Interests`, `Users`, `DeviceToken`) are thin wrappers over these flat functions. Use whichever you like. The flat ones are kept for people coming from the old packages.
3
+ `Interests` and `Users` are thin wrappers over these flat functions. Use whichever you like. The flat ones are kept for people coming from the old packages.
4
4
 
5
- | Function | Modes | Notes |
5
+ | Function | Used for | Notes |
6
6
  |---|---|---|
7
- | `start({ mode?, instanceId?, requestPermission? })` | all | Resolves the device token in `device` mode, otherwise `null`. |
8
- | `getMode()` | all | |
9
- | `subscribe` / `unsubscribe` / `setSubscriptions` / `getSubscriptions` / `clearSubscriptions` | interests (and users) | Work on both platforms. |
10
- | `setUserId(userId, { url, headers?, queryParams? } \| token)` | users | |
11
- | `registerForDeviceToken()` / `getDevicePushToken()` / `deleteDevicePushToken()` | all (main API for `device`) | |
12
- | `requestPermission()` / `getPermissionStatus()` | all | |
13
- | `createChannel` / `deleteChannel` / `getChannels` | all, Android only | |
14
- | `getBadgeCount` / `setBadgeCount` / `incrementBadgeCount` | all | |
15
- | `presentLocalNotification` / `scheduleLocalNotification` / `cancelScheduledNotification` / `cancelAllScheduledNotifications` / `dismissAllNotifications` | all | |
16
- | `getInitialNotification()` | all | |
17
- | `clearAllState()` / `stop()` | all | In `device` mode, `stop()` deletes the device token. |
18
- | `addListener(event, cb)` / `on(event, cb)` | all | Return an `EventSubscription`. |
7
+ | `start({ instanceId, mode?, requestPermission? })` | everything | `mode` (optional) is the Beams auth path: `interests` (default) or `users`. |
8
+ | `getMode()` | everything | |
9
+ | `subscribe` / `unsubscribe` / `setSubscriptions` / `getSubscriptions` / `clearSubscriptions` | interests | Work on both platforms. |
10
+ | `setUserId(userId, { url, headers?, queryParams? } \| token)` | binding a user | |
11
+ | `requestPermission()` / `getPermissionStatus()` | everything | |
12
+ | `createChannel` / `deleteChannel` / `getChannels` | Android only | |
13
+ | `getBadgeCount` / `setBadgeCount` / `incrementBadgeCount` | everything | |
14
+ | `presentLocalNotification` / `scheduleLocalNotification` / `cancelScheduledNotification` / `cancelAllScheduledNotifications` / `dismissAllNotifications` | everything | |
15
+ | `getInitialNotification()` | everything | |
16
+ | `clearAllState()` / `stop()` | everything | |
17
+ | `addListener(event, cb)` / `on(event, cb)` | everything | Return an `EventSubscription`. |
19
18
 
20
19
 
21
20
  ---
package/docs/extras.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Sounds, channels, badges, local notifications
2
2
 
3
- All of this works the same in every mode.
3
+ All of this works whether you use interests, users, or both.
4
4
 
5
5
  ## Custom sounds
6
6
 
package/docs/interests.md CHANGED
@@ -1,6 +1,6 @@
1
- # Mode 1: Beams interests
1
+ # Interests (topics)
2
2
 
3
- **Use this when** many devices should get the same push. Think topics: `news`, `order-42`, `team-7`.
3
+ Use interests when many devices should get the same push. Think topics: `news`, `order-42`, `team-7`.
4
4
  You need a Pusher Beams instance. Your server calls `publishToInterests`.
5
5
 
6
6
  ## Client
package/docs/migrating.md CHANGED
@@ -17,7 +17,11 @@ Here is what the ZeptInc and b8ne packages had, and where it lives now:
17
17
  | `aps.data.incrementBadge` (b8ne, iOS) | Supported on iOS and Android, plus full badge APIs. |
18
18
  | Android launch-intent notification delivery (b8ne) | `getInitialNotification()` and an `opened` event on tap. |
19
19
 
20
- Neither original had custom sounds, notification channels, local or scheduled notifications, or a raw-token mode. Those are new here.
20
+ Neither original had custom sounds, notification channels, or local and scheduled notifications. Those are new here.
21
+
22
+ ## Coming from 0.3
23
+
24
+ 0.4 removes raw device-token support (`DeviceToken`, `registerForDeviceToken`, `getDevicePushToken`, `deleteDevicePushToken`, and `mode: 'device'`). This package is Pusher Beams only now. If you need a raw FCM / APNs token for your own server, use [`expo-notifications`](https://docs.expo.dev/versions/latest/sdk/notifications/) and `getDevicePushTokenAsync()` instead.
21
25
 
22
26
  ## Steps
23
27
 
package/docs/setup.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # Setup
2
2
 
3
- You need this for every mode.
4
-
5
3
  ## Install
6
4
 
7
5
  ```sh
@@ -17,7 +15,6 @@ npx expo install expo-pusher-push-notifications
17
15
  "android": { "package": "com.you.app", "googleServicesFile": "./google-services.json" },
18
16
  "plugins": [
19
17
  ["expo-pusher-push-notifications", {
20
- "mode": "interests",
21
18
  "instanceId": "YOUR_BEAMS_INSTANCE_ID",
22
19
  "apsEnvironment": "development",
23
20
  "sounds": ["./assets/sounds/ding.wav", "./assets/sounds/alarm.caf"],
@@ -40,23 +37,22 @@ Then run `npx expo prebuild` and build a development build. Expo Go cannot load
40
37
 
41
38
  | Option | Default | What it does |
42
39
  |---|---|---|
43
- | `mode` | `interests` | Written to Info.plist and the manifest so native code can read it. |
44
- | `instanceId` | none | Beams instance ID. Not needed for `device` mode. |
40
+ | `mode` | `interests` | Which Beams auth path your app uses: `interests`, or `users` if you bind devices to signed-in users. Written to Info.plist and the manifest. You can leave it out. |
41
+ | `instanceId` | none | Beams instance ID. |
45
42
  | `apsEnvironment` | `development` | Sets the `aps-environment` entitlement. Use `production` for TestFlight and App Store builds. |
46
43
  | `sounds` | `[]` | Sound files to bundle. **Android:** copied to `res/raw` with names lower-cased to `[a-z0-9_]`. **iOS:** copied into the app target and added to its resources. iOS needs `.wav`, `.caf`, or `.aiff` under 30 s. |
47
44
  | `androidChannels` | `[]` | Channels created at startup. Set `sound` to a file name from `sounds`, or `null` for a silent channel. |
48
45
  | `androidDefaultChannelId` | first channel, or `default` | Used by FCM/Beams notifications that don't name a channel. Also sets `com.google.firebase.messaging.default_notification_channel_id`. |
49
46
  | `iosShowInForeground` | `true` | Shows the banner, plays the sound, and updates the badge while the app is in the foreground. |
50
47
 
51
- The plugin also adds the `remote-notification` background mode on iOS. On Android, the library manifest declares one FCM service for all modes (it extends the Beams `MessagingService`), the `POST_NOTIFICATIONS` permission, and a receiver for scheduled local notifications.
48
+ The plugin also adds the `remote-notification` background mode on iOS. On Android, the library manifest declares one FCM service (it extends the Beams `MessagingService`), the `POST_NOTIFICATIONS` permission, and a receiver for scheduled local notifications.
52
49
 
53
50
  ## Console setup
54
51
 
55
- 1. **iOS (all modes):** enable the Push Notifications capability. The plugin sets the entitlement. Create an APNs auth key (.p8).
56
- 2. **Android (all modes):** create a Firebase project, download `google-services.json`, and point `android.googleServicesFile` at it.
57
- 3. **Modes 1 and 2:** create a Beams instance in the [Pusher dashboard](https://dashboard.pusher.com/beams), then upload your APNs key and your FCM service account to it.
58
- 4. **Mode 2:** add an authenticated endpoint to your backend that returns `{ "token": beamsClient.generateToken(userId) }` (see the [Beams auth docs](https://pusher.com/docs/beams/guides/publish-to-specific-user/)).
59
- 5. **Mode 3:** your backend keeps the APNs key and the Firebase service account and calls FCM/APNs itself (examples below).
52
+ 1. **iOS:** enable the Push Notifications capability. The plugin sets the entitlement. Create an APNs auth key (.p8).
53
+ 2. **Android:** create a Firebase project, download `google-services.json`, and point `android.googleServicesFile` at it.
54
+ 3. **Beams:** create a Beams instance in the [Pusher dashboard](https://dashboard.pusher.com/beams), then upload your APNs key and your FCM service account to it.
55
+ 4. **If you bind devices to users:** add an authenticated endpoint to your backend that returns `{ "token": beamsClient.generateToken(userId) }` (see the [Beams auth docs](https://pusher.com/docs/beams/guides/publish-to-specific-user/)).
60
56
 
61
57
  ## Permissions
62
58
 
@@ -65,7 +61,7 @@ The plugin also adds the `remote-notification` background mode on iOS. On Androi
65
61
  ## Things that conflict
66
62
 
67
63
  - **iOS:** the module becomes the `UNUserNotificationCenter` delegate so it can show notifications in the foreground and report taps. Don't use it together with another library that also claims the delegate, such as `expo-notifications`.
68
- - **Android:** only one `FirebaseMessagingService` can receive FCM messages. This module's service handles all three modes, so remove other FCM services such as `expo-notifications` or `@react-native-firebase/messaging`'s service.
64
+ - **Android:** only one `FirebaseMessagingService` can receive FCM messages. This module's service handles it, so remove other FCM services such as `expo-notifications` or `@react-native-firebase/messaging`'s service.
69
65
 
70
66
 
71
67
  ---
package/docs/users.md CHANGED
@@ -1,9 +1,10 @@
1
- # Mode 2: Beams authenticated users
1
+ # Bind a device to a user
2
2
 
3
- **Use this when** your backend thinks in user ids: "send this to user-123", on every device they're signed in on.
4
- You need a Pusher Beams instance and one auth endpoint on your server.
3
+ When your backend thinks in user ids ("send this to user-123"), bind the device to the signed-in user and Beams will deliver to every device they're signed in on.
5
4
 
6
- ## Client
5
+ How it works: after your own sign-in, the app calls `Users.login(userId, …)`. Beams then asks **your API** for a short-lived auth token, which proves this user really is `user-123`. So you need one authenticated endpoint on your server.
6
+
7
+ ## In the app
7
8
 
8
9
  ```ts
9
10
  import { Users } from 'expo-pusher-push-notifications';
@@ -23,7 +24,7 @@ await Users.login('user-123', beamsToken);
23
24
  await Users.logout();
24
25
  ```
25
26
 
26
- ## Server (Node)
27
+ ## On your server (Node)
27
28
 
28
29
  ```js
29
30
  // GET /pusher/beams-auth (must be authenticated, and user_id must match the session)
@@ -49,7 +50,7 @@ See Pusher's [auth guide](https://pusher.com/docs/beams/guides/publish-to-specif
49
50
  | `Users.logout()` | Unbinds the device from the user. |
50
51
  | `Users.stop()` | Stop Beams. |
51
52
 
52
- Interests still work in this mode if you want both.
53
+ You can still subscribe to interests on a device that's bound to a user.
53
54
 
54
55
 
55
56
  ---
@@ -26,7 +26,6 @@ struct LocalNotificationRecord: Record {
26
26
  public class ExpoPusherPushNotificationsModule: Module {
27
27
  private let beams = PushNotifications.shared
28
28
  private var beamsStarted = false
29
- private var tokenWaiters: [Promise] = []
30
29
  private var initialNotification: [String: Any]?
31
30
  private lazy var centerDelegate = NotificationCenterDelegate(module: self)
32
31
 
@@ -40,8 +39,6 @@ public class ExpoPusherPushNotificationsModule: Module {
40
39
  ExpoPusherAppDelegateSubscriber.onTokenError = { [weak self] error in
41
40
  guard let self = self else { return }
42
41
  self.sendEvent("error", ["code": "E_APNS_REGISTRATION", "message": error.localizedDescription])
43
- let waiters = self.tokenWaiters; self.tokenWaiters = []
44
- waiters.forEach { $0.reject("E_APNS_REGISTRATION", error.localizedDescription) }
45
42
  }
46
43
  ExpoPusherAppDelegateSubscriber.onNotification = { [weak self] userInfo, state in
47
44
  self?.handleRemote(userInfo, state: state)
@@ -87,22 +84,6 @@ public class ExpoPusherPushNotificationsModule: Module {
87
84
  self.beams.stop { self.beamsStarted = false; promise.resolve(nil) }
88
85
  }
89
86
 
90
- // ---- Raw device token (APNs) ----
91
- AsyncFunction("registerForDeviceToken") { (promise: Promise) in
92
- if let token = ExpoPusherAppDelegateSubscriber.lastToken {
93
- promise.resolve(Self.tokenDict(token)); return
94
- }
95
- self.tokenWaiters.append(promise)
96
- DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
97
- }
98
- AsyncFunction("getDevicePushToken") { () -> [String: Any]? in
99
- ExpoPusherAppDelegateSubscriber.lastToken.map(Self.tokenDict)
100
- }
101
- AsyncFunction("deleteDevicePushToken") {
102
- ExpoPusherAppDelegateSubscriber.lastToken = nil
103
- DispatchQueue.main.async { UIApplication.shared.unregisterForRemoteNotifications() }
104
- }
105
-
106
87
  // ---- Permissions ----
107
88
  AsyncFunction("requestPermission") { (promise: Promise) in
108
89
  UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { _, _ in
@@ -149,10 +130,8 @@ public class ExpoPusherPushNotificationsModule: Module {
149
130
 
150
131
  private func handleToken(_ token: Data) {
151
132
  if beamsStarted { beams.registerDeviceToken(token) }
152
- let dict = Self.tokenDict(token)
153
- sendEvent("registered", ["deviceToken": dict["token"]!, "type": "apns"])
154
- let waiters = tokenWaiters; tokenWaiters = []
155
- waiters.forEach { $0.resolve(dict) }
133
+ let hex = token.map { String(format: "%02x", $0) }.joined()
134
+ sendEvent("registered", ["deviceToken": hex, "type": "apns"])
156
135
  }
157
136
 
158
137
  fileprivate func handleRemote(_ userInfo: [AnyHashable: Any], state: String) {
@@ -197,10 +176,6 @@ public class ExpoPusherPushNotificationsModule: Module {
197
176
  return UNNotificationSound(named: UNNotificationSoundName(rawValue: name))
198
177
  }
199
178
 
200
- static func tokenDict(_ token: Data) -> [String: Any] {
201
- ["type": "apns", "platform": "ios", "token": token.map { String(format: "%02x", $0) }.joined()]
202
- }
203
-
204
179
  static func payload(userInfo: [AnyHashable: Any], state: String) -> [String: Any] {
205
180
  let alertAny = (userInfo["aps"] as? [String: Any])?["alert"]
206
181
  let alert = alertAny as? [String: Any]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-pusher-push-notifications",
3
- "version": "0.3.0",
4
- "description": "Push notifications for Expo: Pusher Beams (interests or users) or direct FCM/APNs device tokens, with custom sounds, channels, badges and local notifications",
3
+ "version": "0.4.1",
4
+ "description": "Pusher Beams push notifications for Expo (interests and authenticated users), with custom sounds, Android channels, badges and local notifications",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
7
7
  "scripts": {
@@ -24,8 +24,7 @@
24
24
  "push-notifications",
25
25
  "config-plugin",
26
26
  "fcm",
27
- "apns",
28
- "device-token"
27
+ "apns"
29
28
  ],
30
29
  "repository": "https://github.com/baraa-rasheed/expo-pusher-push-notifications",
31
30
  "bugs": {
@@ -10,12 +10,12 @@ export interface PusherPluginChannel {
10
10
  showBadge?: boolean;
11
11
  }
12
12
  export interface PusherPluginProps {
13
- /** Pusher Beams instance ID (not needed for `device` mode). */
13
+ /** Pusher Beams instance ID. */
14
14
  instanceId?: string;
15
15
  /** APNs environment for the aps-environment entitlement. Defaults to "development". */
16
16
  apsEnvironment?: 'development' | 'production';
17
- /** Default mode written to native config. Defaults to "interests". */
18
- mode?: 'interests' | 'users' | 'device';
17
+ /** Beams auth path written to native config (`interests` or `users`). Defaults to "interests". */
18
+ mode?: 'interests' | 'users';
19
19
  /**
20
20
  * Sound files (paths relative to the project root) to bundle. Android: copied to res/raw
21
21
  * (lower-cased, must be [a-z0-9_]). iOS: added to the main bundle. Use .wav/.caf/.aiff for iOS (<30s).
package/docs/direct.md DELETED
@@ -1,63 +0,0 @@
1
- # Mode 3: direct FCM / APNs (no Pusher)
2
-
3
- **Use this when** your server already sends to FCM and APNs itself, or you use some other push provider.
4
- No Beams instance needed. You get the raw native token and do what you want with it.
5
-
6
- ## Client
7
-
8
- ```ts
9
- import { DeviceToken } from 'expo-pusher-push-notifications';
10
-
11
- const token = await DeviceToken.start();
12
- // { type: 'fcm', platform: 'android', token: 'dYz…' }
13
- // { type: 'apns', platform: 'ios', token: 'a1b2…' }
14
- await api.saveDevice(token);
15
-
16
- // Tokens rotate. Keep your backend in sync.
17
- DeviceToken.onChange((t) => api.saveDevice(t));
18
-
19
- await DeviceToken.get(); // last known token, or null
20
- await DeviceToken.delete(); // on sign-out
21
- ```
22
-
23
- Calling a Beams function (`Interests.*`, `Users.*`) in this mode throws.
24
-
25
- ## Server
26
-
27
- Server, FCM HTTP v1 (Android):
28
-
29
- ```http
30
- POST https://fcm.googleapis.com/v1/projects/<project-id>/messages:send
31
- Authorization: Bearer <OAuth2 token from your service account>
32
-
33
- { "message": { "token": "<fcm token>",
34
- "notification": { "title": "Hi", "body": "Direct from FCM" },
35
- "android": { "notification": { "channel_id": "messages", "sound": "ding" } },
36
- "data": { "orderId": "42" } } }
37
- ```
38
-
39
- Data-only FCM messages that include `title`/`body` keys in `data` (plus optional `sound`, `android_channel_id`, and `incrementBadge: "true"`) are shown by this module with the right channel and sound, including in the background.
40
-
41
- Server, APNs (iOS):
42
-
43
- ```http
44
- POST https://api.push.apple.com/3/device/<apns hex token> (api.sandbox.push.apple.com for development)
45
- authorization: bearer <JWT signed with your .p8>
46
- apns-topic: com.you.app
47
- apns-push-type: alert
48
-
49
- { "aps": { "alert": { "title": "Hi", "body": "Direct from APNs" }, "sound": "ding.wav", "badge": 1 }, "orderId": "42" }
50
- ```
51
-
52
- ## API
53
-
54
- | Call | What it does |
55
- |---|---|
56
- | `DeviceToken.start({ requestPermission? })` | Registers with FCM/APNs, resolves the token. |
57
- | `DeviceToken.get()` | Last known token or `null`. |
58
- | `DeviceToken.onChange(cb)` | Fires when the token is issued or rotated. |
59
- | `DeviceToken.delete()` | Android: FCM `deleteToken`. iOS: unregister. |
60
-
61
-
62
- ---
63
- [← Back to README](../README.md)