expo-pusher-push-notifications 0.4.2 → 0.5.0
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 +25 -4
- package/android/src/main/java/expo/modules/pusherpushnotifications/ExpoPusherPushNotificationsModule.kt +21 -0
- package/android/src/main/java/expo/modules/pusherpushnotifications/NotificationHelper.kt +4 -0
- package/android/src/main/java/expo/modules/pusherpushnotifications/PusherMessagingService.kt +3 -2
- package/build/ExpoPusherPushNotifications.types.d.ts +18 -9
- package/build/ExpoPusherPushNotifications.types.d.ts.map +1 -1
- package/build/ExpoPusherPushNotifications.types.js.map +1 -1
- package/build/ExpoPusherPushNotificationsModule.d.ts +4 -1
- package/build/ExpoPusherPushNotificationsModule.d.ts.map +1 -1
- package/build/ExpoPusherPushNotificationsModule.js.map +1 -1
- package/build/index.d.ts +48 -7
- package/build/index.d.ts.map +1 -1
- package/build/index.js +58 -11
- package/build/index.js.map +1 -1
- package/docs/api.md +4 -3
- package/docs/direct.md +42 -0
- package/docs/migrating.md +2 -2
- package/docs/setup.md +3 -3
- package/ios/ExpoPusherPushNotificationsModule.swift +27 -2
- package/package.json +4 -3
- package/plugin/build/index.d.ts +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# expo-pusher-push-notifications
|
|
2
2
|
|
|
3
|
-
Push notifications for Expo and React Native
|
|
3
|
+
Push notifications for Expo and React Native. Two ways to use it:
|
|
4
|
+
|
|
5
|
+
1. **Pusher Beams** — subscribe devices to interests (topics) and/or bind them to your signed-in users. Uses [Pusher Beams](https://pusher.com/beams).
|
|
6
|
+
2. **Device token** — get the raw FCM (Android) / APNs (iOS) token for your own push path. No Beams, no `expo-notifications`, no EAS.
|
|
7
|
+
|
|
8
|
+
Both get custom sounds, Android channels, badges, and local notifications.
|
|
4
9
|
|
|
5
10
|
```sh
|
|
6
11
|
npx expo install expo-pusher-push-notifications
|
|
@@ -27,7 +32,9 @@ await Interests.subscribe('news');
|
|
|
27
32
|
|
|
28
33
|
That device now gets pushes sent to `news`. Full console steps (APNs, Firebase, Beams) are in [Setup](docs/setup.md).
|
|
29
34
|
|
|
30
|
-
##
|
|
35
|
+
## Path 1: Pusher Beams
|
|
36
|
+
|
|
37
|
+
### Subscribe to interests (topics)
|
|
31
38
|
|
|
32
39
|
Interests are topics like `news`, `order-42`, or `team-7`. Every device subscribed to one gets the push.
|
|
33
40
|
|
|
@@ -38,7 +45,7 @@ await Interests.unsubscribe('order-42');
|
|
|
38
45
|
|
|
39
46
|
More in [Interests](docs/interests.md).
|
|
40
47
|
|
|
41
|
-
|
|
48
|
+
### Bind a device to a user
|
|
42
49
|
|
|
43
50
|
To get pushes meant for a specific signed-in user on all their devices, bind the device to that user.
|
|
44
51
|
|
|
@@ -59,6 +66,20 @@ await Users.logout();
|
|
|
59
66
|
|
|
60
67
|
You can use interests and users together. More in [Users](docs/users.md).
|
|
61
68
|
|
|
69
|
+
## Path 2: Device token
|
|
70
|
+
|
|
71
|
+
No Beams instance needed (leave `instanceId` out of the plugin config).
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { DeviceToken } from 'expo-pusher-push-notifications';
|
|
75
|
+
|
|
76
|
+
const token = await DeviceToken.start(); // { type: 'fcm' | 'apns', platform, token }
|
|
77
|
+
DeviceToken.onChange((t) => { /* token rotated */ });
|
|
78
|
+
await DeviceToken.delete(); // on sign-out
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
You get the token in the app; sending it to your backend and pushing from there is up to you. More in [Device token](docs/direct.md).
|
|
82
|
+
|
|
62
83
|
## Extras
|
|
63
84
|
|
|
64
85
|
```ts
|
|
@@ -77,6 +98,7 @@ Custom sounds go in the plugin's `sounds` option. Details in [Extras](docs/extra
|
|
|
77
98
|
- [Setup](docs/setup.md)
|
|
78
99
|
- [Interests](docs/interests.md)
|
|
79
100
|
- [Users](docs/users.md)
|
|
101
|
+
- [Device token](docs/direct.md)
|
|
80
102
|
- [Sounds, channels, badges, local notifications](docs/extras.md)
|
|
81
103
|
- [Full API](docs/api.md)
|
|
82
104
|
- [Migrating from react-native-pusher-push-notifications](docs/migrating.md)
|
|
@@ -84,7 +106,6 @@ Custom sounds go in the plugin's `sounds` option. Details in [Extras](docs/extra
|
|
|
84
106
|
## Good to know
|
|
85
107
|
|
|
86
108
|
- 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`.
|
|
87
|
-
- Want a raw FCM / APNs token without Beams? Use [`expo-notifications`](https://docs.expo.dev/versions/latest/sdk/notifications/) instead.
|
|
88
109
|
- Need realtime Pusher **Channels** (websockets)? Use [`pusher-js`](https://github.com/pusher/pusher-js).
|
|
89
110
|
|
|
90
111
|
## License
|
|
@@ -9,6 +9,7 @@ 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
|
|
12
13
|
import com.pusher.pushnotifications.BeamsCallback
|
|
13
14
|
import com.pusher.pushnotifications.PushNotifications
|
|
14
15
|
import com.pusher.pushnotifications.PusherCallbackError
|
|
@@ -75,6 +76,24 @@ class ExpoPusherPushNotificationsModule : Module() {
|
|
|
75
76
|
AsyncFunction("clearAllState") { PushNotifications.clearAllState() }
|
|
76
77
|
AsyncFunction("stop") { PushNotifications.stop() }
|
|
77
78
|
|
|
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
|
+
|
|
78
97
|
// ---- Permissions ----
|
|
79
98
|
AsyncFunction("requestPermission") { promise: Promise ->
|
|
80
99
|
val perms = appContext.permissions
|
|
@@ -140,6 +159,8 @@ class ExpoPusherPushNotificationsModule : Module() {
|
|
|
140
159
|
override fun onFailure(error: PusherCallbackError) = promise.reject("E_SET_USER_ID", error.message, null)
|
|
141
160
|
}
|
|
142
161
|
|
|
162
|
+
private fun tokenMap(token: String) = mapOf("type" to "fcm", "platform" to "android", "token" to token)
|
|
163
|
+
|
|
143
164
|
private fun status(): String =
|
|
144
165
|
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) PermissionsStatus.GRANTED.status
|
|
145
166
|
else if (Build.VERSION.SDK_INT >= 33) PermissionsStatus.UNDETERMINED.status else PermissionsStatus.DENIED.status
|
|
@@ -106,6 +106,10 @@ 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
|
+
|
|
109
113
|
fun show(ctx: Context, id: Int, title: String?, body: String?, data: Map<String, String>, sound: String?, channelId: String?) {
|
|
110
114
|
ensureChannels(ctx)
|
|
111
115
|
val launch = ctx.packageManager.getLaunchIntentForPackage(ctx.packageName)?.apply {
|
package/android/src/main/java/expo/modules/pusherpushnotifications/PusherMessagingService.kt
CHANGED
|
@@ -4,8 +4,8 @@ import com.google.firebase.messaging.RemoteMessage
|
|
|
4
4
|
import com.pusher.pushnotifications.fcm.MessagingService
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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.
|
|
9
9
|
*/
|
|
10
10
|
class PusherMessagingService : MessagingService() {
|
|
11
11
|
companion object { @Volatile var module: ExpoPusherPushNotificationsModule? = null }
|
|
@@ -39,6 +39,7 @@ class PusherMessagingService : MessagingService() {
|
|
|
39
39
|
|
|
40
40
|
override fun onNewToken(token: String) {
|
|
41
41
|
super.onNewToken(token)
|
|
42
|
+
NotificationHelper.saveToken(this, token)
|
|
42
43
|
module?.emit("registered", mapOf("deviceToken" to token, "type" to "fcm"))
|
|
43
44
|
}
|
|
44
45
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Delivery mode.
|
|
3
3
|
*
|
|
4
|
-
* - `interests`:
|
|
5
|
-
* - `users`:
|
|
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.
|
|
6
8
|
*/
|
|
7
|
-
export type PusherTransportMode = 'interests' | 'users';
|
|
9
|
+
export type PusherTransportMode = 'interests' | 'users' | 'device';
|
|
8
10
|
export interface PusherConfig {
|
|
9
|
-
/** Pusher Beams instance ID. */
|
|
10
|
-
instanceId
|
|
11
|
-
/**
|
|
11
|
+
/** Pusher Beams instance ID. Required for `interests` and `users`; ignored for `device`. */
|
|
12
|
+
instanceId?: string;
|
|
13
|
+
/** Defaults to `interests`. */
|
|
12
14
|
mode?: PusherTransportMode;
|
|
13
15
|
/** Ask for notification permission (iOS alert/sound/badge, Android 13+ POST_NOTIFICATIONS) during start. Default true. */
|
|
14
16
|
requestPermission?: boolean;
|
|
@@ -25,6 +27,13 @@ export interface BeamsTokenProvider {
|
|
|
25
27
|
* (the b8ne `setUserId(userId, token)` style).
|
|
26
28
|
*/
|
|
27
29
|
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
|
+
}
|
|
28
37
|
export interface PusherNotification {
|
|
29
38
|
title?: string;
|
|
30
39
|
body?: string;
|
|
@@ -33,9 +42,9 @@ export interface PusherNotification {
|
|
|
33
42
|
appState: 'foreground' | 'background' | 'opened';
|
|
34
43
|
}
|
|
35
44
|
export interface RegisteredEvent {
|
|
36
|
-
/** Native token
|
|
45
|
+
/** Native device token. In `device` mode this is the token your server sends to. */
|
|
37
46
|
deviceToken: string;
|
|
38
|
-
type:
|
|
47
|
+
type: DevicePushTokenType;
|
|
39
48
|
}
|
|
40
49
|
export interface SubscriptionsChangedEvent {
|
|
41
50
|
interests: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoPusherPushNotifications.types.d.ts","sourceRoot":"","sources":["../src/ExpoPusherPushNotifications.types.ts"],"names":[],"mappings":"AAAA
|
|
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 *
|
|
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 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 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,5 +1,5 @@
|
|
|
1
1
|
import { NativeModule } from 'expo';
|
|
2
|
-
import type { AndroidNotificationChannel, BeamsTokenProvider, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherNotification, ScheduledNotification } from './ExpoPusherPushNotifications.types';
|
|
2
|
+
import type { AndroidNotificationChannel, BeamsTokenProvider, DevicePushToken, 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,6 +11,9 @@ 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>;
|
|
14
17
|
requestPermission(): Promise<PermissionStatus>;
|
|
15
18
|
getPermissionStatus(): Promise<PermissionStatus>;
|
|
16
19
|
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,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
|
+
{"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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoPusherPushNotificationsModule.js","sourceRoot":"","sources":["../src/ExpoPusherPushNotificationsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;
|
|
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"]}
|
package/build/index.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { EventSubscription } from 'expo-modules-core';
|
|
2
|
-
import type { AndroidNotificationChannel, BeamsAuth, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherConfig, PusherEventName, PusherNotification, PusherTransportMode, ScheduledNotification } from './ExpoPusherPushNotifications.types';
|
|
2
|
+
import type { AndroidNotificationChannel, BeamsAuth, DevicePushToken, ExpoPusherPushNotificationsModuleEvents, LocalNotification, PermissionStatus, PusherConfig, PusherEventName, PusherNotification, PusherTransportMode, ScheduledNotification } from './ExpoPusherPushNotifications.types';
|
|
3
3
|
export * from './ExpoPusherPushNotifications.types';
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Starts the module.
|
|
6
|
+
* - Pusher Beams (`interests` / `users`): starts the Beams SDK (requires `instanceId`).
|
|
7
|
+
* - Device token (`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>;
|
|
6
11
|
export declare function getMode(): PusherTransportMode;
|
|
7
12
|
export declare function subscribe(interest: string): Promise<void>;
|
|
8
13
|
export declare function unsubscribe(interest: string): Promise<void>;
|
|
@@ -11,6 +16,12 @@ export declare function getSubscriptions(): Promise<string[]>;
|
|
|
11
16
|
export declare function clearSubscriptions(): Promise<void>;
|
|
12
17
|
/** Pass a token provider `{ url, headers?, queryParams? }` or a pre-fetched Beams token string. */
|
|
13
18
|
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>;
|
|
14
25
|
export declare function requestPermission(): Promise<PermissionStatus>;
|
|
15
26
|
export declare function getPermissionStatus(): Promise<PermissionStatus>;
|
|
16
27
|
export declare function createChannel(channel: AndroidNotificationChannel): Promise<void>;
|
|
@@ -41,7 +52,7 @@ export declare const Interests: {
|
|
|
41
52
|
/** Start Beams. */
|
|
42
53
|
readonly start: (instanceId: string, opts?: {
|
|
43
54
|
requestPermission?: boolean;
|
|
44
|
-
}) => Promise<
|
|
55
|
+
}) => Promise<undefined>;
|
|
45
56
|
readonly subscribe: typeof subscribe;
|
|
46
57
|
readonly unsubscribe: typeof unsubscribe;
|
|
47
58
|
readonly set: typeof setSubscriptions;
|
|
@@ -60,19 +71,35 @@ export declare const Users: {
|
|
|
60
71
|
/** Start Beams. Call `login()` after your own sign-in. */
|
|
61
72
|
readonly start: (instanceId: string, opts?: {
|
|
62
73
|
requestPermission?: boolean;
|
|
63
|
-
}) => Promise<
|
|
74
|
+
}) => Promise<undefined>;
|
|
64
75
|
/** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */
|
|
65
76
|
readonly login: typeof setUserId;
|
|
66
77
|
/** Unbind the device (call on sign-out). */
|
|
67
78
|
readonly logout: typeof clearAllState;
|
|
68
79
|
readonly stop: typeof stop;
|
|
69
80
|
};
|
|
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
|
+
};
|
|
70
97
|
declare const _default: {
|
|
71
98
|
readonly Interests: {
|
|
72
99
|
/** Start Beams. */
|
|
73
100
|
readonly start: (instanceId: string, opts?: {
|
|
74
101
|
requestPermission?: boolean;
|
|
75
|
-
}) => Promise<
|
|
102
|
+
}) => Promise<undefined>;
|
|
76
103
|
readonly subscribe: typeof subscribe;
|
|
77
104
|
readonly unsubscribe: typeof unsubscribe;
|
|
78
105
|
readonly set: typeof setSubscriptions;
|
|
@@ -86,13 +113,24 @@ declare const _default: {
|
|
|
86
113
|
/** Start Beams. Call `login()` after your own sign-in. */
|
|
87
114
|
readonly start: (instanceId: string, opts?: {
|
|
88
115
|
requestPermission?: boolean;
|
|
89
|
-
}) => Promise<
|
|
116
|
+
}) => Promise<undefined>;
|
|
90
117
|
/** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */
|
|
91
118
|
readonly login: typeof setUserId;
|
|
92
119
|
/** Unbind the device (call on sign-out). */
|
|
93
120
|
readonly logout: typeof clearAllState;
|
|
94
121
|
readonly stop: typeof stop;
|
|
95
122
|
};
|
|
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
|
+
};
|
|
96
134
|
readonly start: typeof start;
|
|
97
135
|
readonly getMode: typeof getMode;
|
|
98
136
|
readonly subscribe: typeof subscribe;
|
|
@@ -101,6 +139,9 @@ declare const _default: {
|
|
|
101
139
|
readonly getSubscriptions: typeof getSubscriptions;
|
|
102
140
|
readonly clearSubscriptions: typeof clearSubscriptions;
|
|
103
141
|
readonly setUserId: typeof setUserId;
|
|
142
|
+
readonly registerForDeviceToken: typeof registerForDeviceToken;
|
|
143
|
+
readonly getDevicePushToken: typeof getDevicePushToken;
|
|
144
|
+
readonly deleteDevicePushToken: typeof deleteDevicePushToken;
|
|
104
145
|
readonly requestPermission: typeof requestPermission;
|
|
105
146
|
readonly getPermissionStatus: typeof getPermissionStatus;
|
|
106
147
|
readonly createChannel: typeof createChannel;
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,SAAS,EACT,uCAAuC,EACvC,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAE7C,cAAc,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/build/index.js
CHANGED
|
@@ -6,16 +6,31 @@ 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
|
+
}
|
|
9
12
|
}
|
|
10
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Starts the module.
|
|
15
|
+
* - Pusher Beams (`interests` / `users`): starts the Beams SDK (requires `instanceId`).
|
|
16
|
+
* - Device token (`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
|
+
*/
|
|
11
19
|
export async function start(config) {
|
|
12
|
-
|
|
13
|
-
throw new Error(`${PREFIX}: instanceId is required.`);
|
|
20
|
+
const mode = config.mode ?? 'interests';
|
|
14
21
|
if (config.requestPermission !== false)
|
|
15
22
|
await Native.requestPermission();
|
|
16
|
-
currentMode =
|
|
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.`);
|
|
17
31
|
await Native.start(config.instanceId);
|
|
18
32
|
started = true;
|
|
33
|
+
return null;
|
|
19
34
|
}
|
|
20
35
|
export function getMode() {
|
|
21
36
|
return currentMode;
|
|
@@ -50,6 +65,19 @@ export async function setUserId(userId, auth) {
|
|
|
50
65
|
else
|
|
51
66
|
await Native.setUserId(userId, auth);
|
|
52
67
|
}
|
|
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
|
+
}
|
|
53
81
|
// ---- Permissions ----
|
|
54
82
|
export function requestPermission() {
|
|
55
83
|
return Native.requestPermission();
|
|
@@ -103,10 +131,14 @@ export function getInitialNotification() {
|
|
|
103
131
|
}
|
|
104
132
|
// ---- Common ----
|
|
105
133
|
export async function clearAllState() {
|
|
106
|
-
|
|
134
|
+
if (currentMode !== 'device')
|
|
135
|
+
await Native.clearAllState();
|
|
107
136
|
}
|
|
108
137
|
export async function stop() {
|
|
109
|
-
|
|
138
|
+
if (currentMode === 'device')
|
|
139
|
+
await Native.deleteDevicePushToken();
|
|
140
|
+
else
|
|
141
|
+
await Native.stop();
|
|
110
142
|
started = false;
|
|
111
143
|
}
|
|
112
144
|
/** Adds an event listener. Events fire for interests and users alike. */
|
|
@@ -116,8 +148,8 @@ export function addListener(eventName, listener) {
|
|
|
116
148
|
/** Alias for `addListener` (old package's `on()`). */
|
|
117
149
|
export const on = addListener;
|
|
118
150
|
// ---------------------------------------------------------------------------
|
|
119
|
-
//
|
|
120
|
-
// channels, badges, local notifications
|
|
151
|
+
// Two paths: Pusher Beams (Interests / Users) or DeviceToken (raw FCM/APNs).
|
|
152
|
+
// Sounds, channels, badges, local notifications and events work on both.
|
|
121
153
|
// ---------------------------------------------------------------------------
|
|
122
154
|
/**
|
|
123
155
|
* Pusher Beams **interests** (topic broadcast).
|
|
@@ -126,7 +158,7 @@ export const on = addListener;
|
|
|
126
158
|
*/
|
|
127
159
|
export const Interests = {
|
|
128
160
|
/** Start Beams. */
|
|
129
|
-
start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'interests' }),
|
|
161
|
+
start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'interests' }).then(() => undefined),
|
|
130
162
|
subscribe,
|
|
131
163
|
unsubscribe,
|
|
132
164
|
set: setSubscriptions,
|
|
@@ -143,18 +175,33 @@ export const Interests = {
|
|
|
143
175
|
*/
|
|
144
176
|
export const Users = {
|
|
145
177
|
/** Start Beams. Call `login()` after your own sign-in. */
|
|
146
|
-
start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'users' }),
|
|
178
|
+
start: (instanceId, opts = {}) => start({ ...opts, instanceId, mode: 'users' }).then(() => undefined),
|
|
147
179
|
/** Bind this device to `userId`. `auth` is your token endpoint, or a Beams token you already fetched. */
|
|
148
180
|
login: setUserId,
|
|
149
181
|
/** Unbind the device (call on sign-out). */
|
|
150
182
|
logout: clearAllState,
|
|
151
183
|
stop,
|
|
152
184
|
};
|
|
185
|
+
/**
|
|
186
|
+
* Mode 3 — **direct FCM / APNs** (no Pusher at all).
|
|
187
|
+
* Use when your server already talks to FCM HTTP v1 / APNs, or you use another provider.
|
|
188
|
+
* You get the raw native token; send it to your backend and keep it fresh via the `registered` event.
|
|
189
|
+
*/
|
|
190
|
+
export const DeviceToken = {
|
|
191
|
+
/** Register with FCM/APNs and resolve the native token. */
|
|
192
|
+
start: async (opts = {}) => (await start({ ...opts, mode: 'device' })),
|
|
193
|
+
get: getDevicePushToken,
|
|
194
|
+
/** Fires whenever the token is issued or rotated. */
|
|
195
|
+
onChange: (cb) => addListener('registered', ({ deviceToken, type }) => cb({ token: deviceToken, type, platform: type === 'fcm' ? 'android' : 'ios' })),
|
|
196
|
+
/** Delete the token (call on sign-out). */
|
|
197
|
+
delete: deleteDevicePushToken,
|
|
198
|
+
};
|
|
153
199
|
export default {
|
|
154
|
-
Interests, Users,
|
|
200
|
+
Interests, Users, DeviceToken,
|
|
155
201
|
start, getMode,
|
|
156
202
|
subscribe, unsubscribe, setSubscriptions, getSubscriptions, clearSubscriptions,
|
|
157
203
|
setUserId,
|
|
204
|
+
registerForDeviceToken, getDevicePushToken, deleteDevicePushToken,
|
|
158
205
|
requestPermission, getPermissionStatus,
|
|
159
206
|
createChannel, deleteChannel, getChannels,
|
|
160
207
|
getBadgeCount, setBadgeCount, incrementBadgeCount,
|
package/build/index.js.map
CHANGED
|
@@ -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 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"]}
|
|
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.\n * - Pusher Beams (`interests` / `users`): starts the Beams SDK (requires `instanceId`).\n * - Device token (`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// ---- 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// ---- 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 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// Two paths: Pusher Beams (Interests / Users) or DeviceToken (raw FCM/APNs).\n// Sounds, channels, badges, local notifications and events work on both.\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' }).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 * 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' }).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"]}
|
package/docs/api.md
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
# Full API
|
|
2
2
|
|
|
3
|
-
`Interests` and `
|
|
3
|
+
`Interests`, `Users` and `DeviceToken` 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
5
|
| Function | Used for | Notes |
|
|
6
6
|
|---|---|---|
|
|
7
|
-
| `start({ instanceId
|
|
7
|
+
| `start({ instanceId?, mode?, requestPermission? })` | everything | `mode`: `interests` (default) or `users` for Beams, `device` for a raw token (no `instanceId`). Resolves the token in `device` mode, otherwise `null`. |
|
|
8
8
|
| `getMode()` | everything | |
|
|
9
9
|
| `subscribe` / `unsubscribe` / `setSubscriptions` / `getSubscriptions` / `clearSubscriptions` | interests | Work on both platforms. |
|
|
10
10
|
| `setUserId(userId, { url, headers?, queryParams? } \| token)` | binding a user | |
|
|
11
|
+
| `registerForDeviceToken()` / `getDevicePushToken()` / `deleteDevicePushToken()` | device token | |
|
|
11
12
|
| `requestPermission()` / `getPermissionStatus()` | everything | |
|
|
12
13
|
| `createChannel` / `deleteChannel` / `getChannels` | Android only | |
|
|
13
14
|
| `getBadgeCount` / `setBadgeCount` / `incrementBadgeCount` | everything | |
|
|
14
15
|
| `presentLocalNotification` / `scheduleLocalNotification` / `cancelScheduledNotification` / `cancelAllScheduledNotifications` / `dismissAllNotifications` | everything | |
|
|
15
16
|
| `getInitialNotification()` | everything | |
|
|
16
|
-
| `clearAllState()` / `stop()` | everything | |
|
|
17
|
+
| `clearAllState()` / `stop()` | everything | In `device` mode, `stop()` deletes the device token. |
|
|
17
18
|
| `addListener(event, cb)` / `on(event, cb)` | everything | Return an `EventSubscription`. |
|
|
18
19
|
|
|
19
20
|
|
package/docs/direct.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Device token (raw FCM / APNs, no Beams)
|
|
2
|
+
|
|
3
|
+
**Use this when** your app has its own push path: your backend (or another provider) sends to FCM and APNs directly.
|
|
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
|
+
## Sending
|
|
26
|
+
|
|
27
|
+
Your backend stores the token and sends to FCM (Android) or APNs (iOS) itself. This module only gets the token and shows the notifications it receives; it doesn't need Beams, `expo-notifications`, or EAS.
|
|
28
|
+
|
|
29
|
+
Data-only FCM messages with `title`/`body` in `data` (plus optional `sound`, `android_channel_id`, `incrementBadge: "true"`) are shown with the right channel and sound, including in the background.
|
|
30
|
+
|
|
31
|
+
## API
|
|
32
|
+
|
|
33
|
+
| Call | What it does |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `DeviceToken.start({ requestPermission? })` | Registers with FCM/APNs, resolves the token. |
|
|
36
|
+
| `DeviceToken.get()` | Last known token or `null`. |
|
|
37
|
+
| `DeviceToken.onChange(cb)` | Fires when the token is issued or rotated. |
|
|
38
|
+
| `DeviceToken.delete()` | Android: FCM `deleteToken`. iOS: unregister. |
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
[← Back to README](../README.md)
|
package/docs/migrating.md
CHANGED
|
@@ -19,9 +19,9 @@ Here is what the ZeptInc and b8ne packages had, and where it lives now:
|
|
|
19
19
|
|
|
20
20
|
Neither original had custom sounds, notification channels, or local and scheduled notifications. Those are new here.
|
|
21
21
|
|
|
22
|
-
## Coming from 0.
|
|
22
|
+
## Coming from 0.4
|
|
23
23
|
|
|
24
|
-
0.
|
|
24
|
+
0.5 brings back device-token support (`DeviceToken`, `registerForDeviceToken`, `getDevicePushToken`, `deleteDevicePushToken`, and `mode: 'device'`), same API as 0.3. Beams code from 0.4 keeps working unchanged.
|
|
25
25
|
|
|
26
26
|
## Steps
|
|
27
27
|
|
package/docs/setup.md
CHANGED
|
@@ -37,8 +37,8 @@ Then run `npx expo prebuild` and build a development build. Expo Go cannot load
|
|
|
37
37
|
|
|
38
38
|
| Option | Default | What it does |
|
|
39
39
|
|---|---|---|
|
|
40
|
-
| `mode` | `interests` |
|
|
41
|
-
| `instanceId` | none | Beams instance ID. |
|
|
40
|
+
| `mode` | `interests` | `interests` or `users` for Beams, or `device` for a raw device token. Written to Info.plist and the manifest. You can leave it out. |
|
|
41
|
+
| `instanceId` | none | Beams instance ID. Not needed for `device`. |
|
|
42
42
|
| `apsEnvironment` | `development` | Sets the `aps-environment` entitlement. Use `production` for TestFlight and App Store builds. |
|
|
43
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. |
|
|
44
44
|
| `androidChannels` | `[]` | Channels created at startup. Set `sound` to a file name from `sounds`, or `null` for a silent channel. |
|
|
@@ -51,7 +51,7 @@ The plugin also adds the `remote-notification` background mode on iOS. On Androi
|
|
|
51
51
|
|
|
52
52
|
1. **iOS:** enable the Push Notifications capability. The plugin sets the entitlement. Create an APNs auth key (.p8).
|
|
53
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.
|
|
54
|
+
3. **Beams path only:** 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
55
|
|
|
56
56
|
## Permissions
|
|
57
57
|
|
|
@@ -26,6 +26,7 @@ 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] = []
|
|
29
30
|
private var initialNotification: [String: Any]?
|
|
30
31
|
private lazy var centerDelegate = NotificationCenterDelegate(module: self)
|
|
31
32
|
|
|
@@ -39,6 +40,8 @@ public class ExpoPusherPushNotificationsModule: Module {
|
|
|
39
40
|
ExpoPusherAppDelegateSubscriber.onTokenError = { [weak self] error in
|
|
40
41
|
guard let self = self else { return }
|
|
41
42
|
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) }
|
|
42
45
|
}
|
|
43
46
|
ExpoPusherAppDelegateSubscriber.onNotification = { [weak self] userInfo, state in
|
|
44
47
|
self?.handleRemote(userInfo, state: state)
|
|
@@ -84,6 +87,22 @@ public class ExpoPusherPushNotificationsModule: Module {
|
|
|
84
87
|
self.beams.stop { self.beamsStarted = false; promise.resolve(nil) }
|
|
85
88
|
}
|
|
86
89
|
|
|
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
|
+
|
|
87
106
|
// ---- Permissions ----
|
|
88
107
|
AsyncFunction("requestPermission") { (promise: Promise) in
|
|
89
108
|
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { _, _ in
|
|
@@ -130,8 +149,10 @@ public class ExpoPusherPushNotificationsModule: Module {
|
|
|
130
149
|
|
|
131
150
|
private func handleToken(_ token: Data) {
|
|
132
151
|
if beamsStarted { beams.registerDeviceToken(token) }
|
|
133
|
-
let
|
|
134
|
-
sendEvent("registered", ["deviceToken":
|
|
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) }
|
|
135
156
|
}
|
|
136
157
|
|
|
137
158
|
fileprivate func handleRemote(_ userInfo: [AnyHashable: Any], state: String) {
|
|
@@ -176,6 +197,10 @@ public class ExpoPusherPushNotificationsModule: Module {
|
|
|
176
197
|
return UNNotificationSound(named: UNNotificationSoundName(rawValue: name))
|
|
177
198
|
}
|
|
178
199
|
|
|
200
|
+
static func tokenDict(_ token: Data) -> [String: Any] {
|
|
201
|
+
["type": "apns", "platform": "ios", "token": token.map { String(format: "%02x", $0) }.joined()]
|
|
202
|
+
}
|
|
203
|
+
|
|
179
204
|
static func payload(userInfo: [AnyHashable: Any], state: String) -> [String: Any] {
|
|
180
205
|
let alertAny = (userInfo["aps"] as? [String: Any])?["alert"]
|
|
181
206
|
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.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Push notifications for Expo: Pusher Beams (interests / users) or raw FCM/APNs device tokens (no EAS needed), with custom sounds, channels, badges and local notifications",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"push-notifications",
|
|
25
25
|
"config-plugin",
|
|
26
26
|
"fcm",
|
|
27
|
-
"apns"
|
|
27
|
+
"apns",
|
|
28
|
+
"device-token"
|
|
28
29
|
],
|
|
29
30
|
"repository": "https://github.com/baraa-rasheed/expo-pusher-push-notifications",
|
|
30
31
|
"bugs": {
|
package/plugin/build/index.d.ts
CHANGED
|
@@ -10,12 +10,12 @@ export interface PusherPluginChannel {
|
|
|
10
10
|
showBadge?: boolean;
|
|
11
11
|
}
|
|
12
12
|
export interface PusherPluginProps {
|
|
13
|
-
/** Pusher Beams instance ID. */
|
|
13
|
+
/** Pusher Beams instance ID (not needed for `device` mode). */
|
|
14
14
|
instanceId?: string;
|
|
15
15
|
/** APNs environment for the aps-environment entitlement. Defaults to "development". */
|
|
16
16
|
apsEnvironment?: 'development' | 'production';
|
|
17
|
-
/**
|
|
18
|
-
mode?: 'interests' | 'users';
|
|
17
|
+
/** Default mode written to native config. Defaults to "interests". */
|
|
18
|
+
mode?: 'interests' | 'users' | 'device';
|
|
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).
|