expo-pusher-push-notifications 0.5.0 → 0.5.2
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 +76 -6
- package/docs/direct.md +2 -0
- package/docs/interests.md +2 -0
- package/docs/migrating.md +84 -19
- package/docs/setup.md +32 -4
- package/docs/users.md +2 -0
- package/package.json +2 -1
- package/skills/migrate-from-b8ne/SKILL.md +73 -0
package/README.md
CHANGED
|
@@ -7,22 +7,48 @@ Push notifications for Expo and React Native. Two ways to use it:
|
|
|
7
7
|
|
|
8
8
|
Both get custom sounds, Android channels, badges, and local notifications.
|
|
9
9
|
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
Do these before installing. Which ones you need depends on your path.
|
|
13
|
+
|
|
14
|
+
**Android (all paths)**
|
|
15
|
+
|
|
16
|
+
1. Create a project in the [Firebase console](https://console.firebase.google.com) and add an Android app with your `android.package`.
|
|
17
|
+
2. Download `google-services.json` into your project and set `"android": { "googleServicesFile": "./google-services.json" }` in `app.json`.
|
|
18
|
+
3. Beams path only: in Firebase → Project settings → Service accounts, generate a private key (JSON). You'll upload it to Beams.
|
|
19
|
+
|
|
20
|
+
**Apple (all paths)**
|
|
21
|
+
|
|
22
|
+
1. In your Apple Developer account, enable the **Push Notifications** capability on your App ID (`ios.bundleIdentifier`).
|
|
23
|
+
2. Create an **APNs auth key (.p8)** under Keys (note the Key ID and Team ID). A .p12 certificate works too, but the key is simpler and doesn't expire.
|
|
24
|
+
3. Set `apsEnvironment` in the plugin: `development` for dev builds, `production` for TestFlight / App Store. The plugin writes the `aps-environment` entitlement for you.
|
|
25
|
+
|
|
26
|
+
**Beams (Interests / Users paths only)**
|
|
27
|
+
|
|
28
|
+
Create a Beams instance in the [Pusher dashboard](https://dashboard.pusher.com/beams), upload your APNs key and FCM service account JSON, and copy the instance ID. Skip this entirely for the device-token path.
|
|
29
|
+
|
|
30
|
+
Full details in [Setup](docs/setup.md).
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
10
34
|
```sh
|
|
11
35
|
npx expo install expo-pusher-push-notifications
|
|
12
36
|
```
|
|
13
37
|
|
|
14
|
-
Needs Expo SDK 58+ and a development build (Expo Go can't load native modules).
|
|
38
|
+
Needs Expo SDK 58+ and a development build (Expo Go can't load native modules). Run `npx expo prebuild` after adding the plugin.
|
|
39
|
+
|
|
40
|
+
## Getting started
|
|
15
41
|
|
|
16
|
-
|
|
42
|
+
Pick the path that matches how you send pushes. You can combine Interests and Users; DeviceToken is for when you don't use Beams at all.
|
|
17
43
|
|
|
18
|
-
|
|
44
|
+
### Interests (Beams topics)
|
|
45
|
+
|
|
46
|
+
`app.json`:
|
|
19
47
|
|
|
20
48
|
```json
|
|
21
49
|
["expo-pusher-push-notifications", { "instanceId": "YOUR_BEAMS_INSTANCE_ID" }]
|
|
22
50
|
```
|
|
23
51
|
|
|
24
|
-
Then in your app:
|
|
25
|
-
|
|
26
52
|
```ts
|
|
27
53
|
import { Interests } from 'expo-pusher-push-notifications';
|
|
28
54
|
|
|
@@ -30,7 +56,43 @@ await Interests.start('YOUR_BEAMS_INSTANCE_ID');
|
|
|
30
56
|
await Interests.subscribe('news');
|
|
31
57
|
```
|
|
32
58
|
|
|
33
|
-
That device now gets pushes sent to `news`.
|
|
59
|
+
That device now gets pushes sent to `news`.
|
|
60
|
+
|
|
61
|
+
### Users (Beams, bind to your signed-in user)
|
|
62
|
+
|
|
63
|
+
`app.json`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
["expo-pusher-push-notifications", { "instanceId": "YOUR_BEAMS_INSTANCE_ID", "mode": "users" }]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { Users } from 'expo-pusher-push-notifications';
|
|
71
|
+
|
|
72
|
+
await Users.start('YOUR_BEAMS_INSTANCE_ID');
|
|
73
|
+
// after your own sign-in; url = your Beams token provider
|
|
74
|
+
await Users.login('user-123', {
|
|
75
|
+
url: 'YOUR_BEAMS_TOKEN_URL',
|
|
76
|
+
headers: { Authorization: `Bearer ${sessionToken}` },
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
That user now gets pushes on every device they're signed in on.
|
|
81
|
+
|
|
82
|
+
### DeviceToken (no Beams)
|
|
83
|
+
|
|
84
|
+
`app.json` — no `instanceId`:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
["expo-pusher-push-notifications", { "mode": "device" }]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { DeviceToken } from 'expo-pusher-push-notifications';
|
|
92
|
+
|
|
93
|
+
const { type, token } = await DeviceToken.start(); // type: 'fcm' | 'apns'
|
|
94
|
+
// send token to your backend, which pushes via FCM / APNs directly
|
|
95
|
+
```
|
|
34
96
|
|
|
35
97
|
## Path 1: Pusher Beams
|
|
36
98
|
|
|
@@ -103,6 +165,14 @@ Custom sounds go in the plugin's `sounds` option. Details in [Extras](docs/extra
|
|
|
103
165
|
- [Full API](docs/api.md)
|
|
104
166
|
- [Migrating from react-native-pusher-push-notifications](docs/migrating.md)
|
|
105
167
|
|
|
168
|
+
## Agent migration
|
|
169
|
+
|
|
170
|
+
Migrating from `react-native-pusher-push-notifications` (b8ne / forks) with Cursor, Claude, Grok or another coding agent? Tell it:
|
|
171
|
+
|
|
172
|
+
> Follow `node_modules/expo-pusher-push-notifications/skills/migrate-from-b8ne/SKILL.md` to migrate this app.
|
|
173
|
+
|
|
174
|
+
The skill has the inventory commands, search/replace table, native cleanup steps and a checklist. Human version: [Migrating](docs/migrating.md). Copy it into `.cursor/skills/` or `.claude/skills/` to make it auto-discoverable.
|
|
175
|
+
|
|
106
176
|
## Good to know
|
|
107
177
|
|
|
108
178
|
- 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`.
|
package/docs/direct.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Device token (raw FCM / APNs, no Beams)
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
> Before you start: finish the [Prerequisites](setup.md#prerequisites) (Firebase + APNs; no Beams instance needed).
|
|
3
5
|
**Use this when** your app has its own push path: your backend (or another provider) sends to FCM and APNs directly.
|
|
4
6
|
No Beams instance needed. You get the raw native token and do what you want with it.
|
|
5
7
|
|
package/docs/interests.md
CHANGED
package/docs/migrating.md
CHANGED
|
@@ -1,32 +1,97 @@
|
|
|
1
1
|
# Migrating from react-native-pusher-push-notifications
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Covers [`b8ne/react-native-pusher-push-notifications`](https://github.com/b8ne/react-native-pusher-push-notifications) (and its forks such as ZeptInc / pusher-community) → `expo-pusher-push-notifications` **0.5.x**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **This is not a drop-in replacement.** The API is promise-based, start-up is a single `start()`/`Interests.start()` call, and native setup moves from hand-edited AppDelegate/MainApplication code to an Expo config plugin. Budget a small refactor, not a package swap.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Using an AI agent? Point it at [`skills/migrate-from-b8ne/SKILL.md`](../skills/migrate-from-b8ne/SKILL.md) (shipped in the npm package).
|
|
8
|
+
|
|
9
|
+
## 1. Install / remove
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm uninstall react-native-pusher-push-notifications
|
|
13
|
+
npx expo install expo-pusher-push-notifications
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Requires an Expo dev build / prebuild (not Expo Go). Bare RN apps need `expo` modules installed (`npx install-expo-modules`).
|
|
17
|
+
|
|
18
|
+
## 2. Native setup: config plugin instead of AppDelegate edits
|
|
19
|
+
|
|
20
|
+
| Old (manual) | New |
|
|
8
21
|
|---|---|
|
|
9
|
-
| `
|
|
10
|
-
| `
|
|
11
|
-
| `
|
|
12
|
-
|
|
|
13
|
-
| `setUserId(userId, token, onError, onSuccess)` (b8ne, static token) | `setUserId(userId, token)`. A remote token provider is also supported. |
|
|
14
|
-
| `clearAllState` (b8ne) | `clearAllState()` |
|
|
15
|
-
| `on('registered' \| 'notification')` | Same, plus `error`, and it returns a removable subscription. |
|
|
16
|
-
| iOS foreground / background / opened states | `appState` on every notification. |
|
|
17
|
-
| `aps.data.incrementBadge` (b8ne, iOS) | Supported on iOS and Android, plus full badge APIs. |
|
|
18
|
-
| Android launch-intent notification delivery (b8ne) | `getInitialNotification()` and an `opened` event on tap. |
|
|
19
|
-
|
|
20
|
-
Neither original had custom sounds, notification channels, or local and scheduled notifications. Those are new here.
|
|
22
|
+
| Carthage/CocoaPods `PushNotifications` framework, `RNPusherPushNotifications` imports | Autolinking (pods pulled automatically) |
|
|
23
|
+
| AppDelegate: `didRegisterForRemoteNotificationsWithDeviceToken` → `[[RNPusherPushNotifications alloc] setDeviceToken:]`, `didReceiveRemoteNotification` forwarding | Expo AppDelegate subscriber in this module – **delete** those lines |
|
|
24
|
+
| Android: `google-services.json` + gradle plugin lines, `MainApplication` / manifest service edits | Plugin config + `android.googleServicesFile` in app.json |
|
|
25
|
+
| Push capability / background modes toggled in Xcode | Added by the plugin on prebuild |
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"expo": {
|
|
30
|
+
"android": { "googleServicesFile": "./google-services.json" },
|
|
31
|
+
"plugins": [["expo-pusher-push-notifications", { "instanceId": "YOUR_BEAMS_INSTANCE_ID" }]]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
Then `npx expo prebuild --clean`. See [Setup](setup.md).
|
|
25
37
|
|
|
26
|
-
##
|
|
38
|
+
## 3. API mapping
|
|
39
|
+
|
|
40
|
+
| b8ne / forks | expo-pusher-push-notifications 0.5 |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `import RNPusherPushNotifications from 'react-native-pusher-push-notifications'` | `import { Interests, Users, on } from 'expo-pusher-push-notifications'` |
|
|
43
|
+
| `setInstanceId(id)` (+ `setAppKey` on some forks) | `await Interests.start(id)` or `await start({ instanceId: id })` |
|
|
44
|
+
| `subscribe(interest, onError, onSuccess)` | `await Interests.subscribe(interest)` (try/catch) |
|
|
45
|
+
| `unsubscribe(interest, onError, onSuccess)` | `await Interests.unsubscribe(interest)` |
|
|
46
|
+
| `setSubscriptions(arr)` (iOS only) | `await Interests.set(arr)` (both platforms) |
|
|
47
|
+
| `getSubscriptions(cb)` (Android only) | `const list = await Interests.get()` |
|
|
48
|
+
| `setOnSubscriptionsChangedListener(cb)` | `on('subscriptionsChanged', cb)` |
|
|
49
|
+
| `setUserId(userId, token, onError, onSuccess)` | `await Users.start(id)` then `await Users.login(userId, token)` — or pass `{ url, headers }` token provider instead of a static token |
|
|
50
|
+
| `clearAllState()` | `await Users.logout()` / `Interests.reset()` / `clearAllState()` |
|
|
51
|
+
| `on('registered', cb)` | `const sub = on('registered', cb)`; later `sub.remove()` |
|
|
52
|
+
| `on('notification', cb)` with iOS `appState` | Same; `appState` on both platforms; also `opened` and `error` events |
|
|
53
|
+
| Android launch-intent delivery | `await getInitialNotification()` + `on('opened', …)` |
|
|
54
|
+
| `aps.data.incrementBadge` | Supported both platforms + `setBadgeCount` / `incrementBadgeCount` |
|
|
55
|
+
| _(none)_ | Sounds, Android channels, local/scheduled notifications, raw device tokens (`DeviceToken`) |
|
|
27
56
|
|
|
28
|
-
|
|
57
|
+
### Before / after
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
// before
|
|
61
|
+
RNPusherPushNotifications.setInstanceId(INSTANCE_ID);
|
|
62
|
+
RNPusherPushNotifications.on('registered', () => {
|
|
63
|
+
RNPusherPushNotifications.subscribe('news', err => console.warn(err), () => console.log('ok'));
|
|
64
|
+
});
|
|
65
|
+
RNPusherPushNotifications.on('notification', n => handle(n));
|
|
66
|
+
|
|
67
|
+
// after
|
|
68
|
+
import { Interests, on } from 'expo-pusher-push-notifications';
|
|
69
|
+
const sub = on('notification', n => handle(n));
|
|
70
|
+
await Interests.start(INSTANCE_ID); // no need to wait for 'registered'
|
|
71
|
+
await Interests.subscribe('news');
|
|
72
|
+
// cleanup: sub.remove();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// users — before
|
|
77
|
+
RNPusherPushNotifications.setUserId(userId, beamsToken, onError, onSuccess);
|
|
78
|
+
// after
|
|
79
|
+
await Users.start(INSTANCE_ID);
|
|
80
|
+
await Users.login(userId, { url: 'https://api.example.com/beams-token', headers: { Authorization: `Bearer ${jwt}` } });
|
|
81
|
+
// sign-out
|
|
82
|
+
await Users.logout();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 4. Gotchas
|
|
86
|
+
|
|
87
|
+
- Notification payload shape may differ slightly; log one and update field access (`n.title`, `n.body`, `n.data`).
|
|
88
|
+
- Don't run alongside `expo-notifications` or `@react-native-firebase/messaging` (this module owns the delegate/FCM service).
|
|
89
|
+
- `start()` requests notification permission by default; pass `{ requestPermission: false }` to control it yourself.
|
|
90
|
+
- Calling Beams APIs before `start()` throws.
|
|
91
|
+
|
|
92
|
+
## Coming from 0.4
|
|
29
93
|
|
|
94
|
+
0.5 brings back device-token support (`DeviceToken`, `registerForDeviceToken`, `getDevicePushToken`, `deleteDevicePushToken`, `mode: 'device'`). Beams code from 0.4 is unchanged.
|
|
30
95
|
|
|
31
96
|
---
|
|
32
97
|
[← Back to README](../README.md)
|
package/docs/setup.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Setup
|
|
2
2
|
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
Set these up first. Android and Apple steps apply to every path; the Beams step only to Interests / Users.
|
|
6
|
+
|
|
7
|
+
### Android: Firebase / FCM
|
|
8
|
+
|
|
9
|
+
1. Create a project in the [Firebase console](https://console.firebase.google.com).
|
|
10
|
+
2. Add an Android app whose package name matches `android.package` in `app.json`.
|
|
11
|
+
3. Download `google-services.json`, put it in your project root, and set `"android": { "googleServicesFile": "./google-services.json" }`.
|
|
12
|
+
4. **Beams only:** Project settings → Service accounts → *Generate new private key*. Keep the JSON for the Beams dashboard.
|
|
13
|
+
|
|
14
|
+
### Apple: APNs
|
|
15
|
+
|
|
16
|
+
1. In [Apple Developer → Identifiers](https://developer.apple.com/account/resources/identifiers/list), open your App ID (`ios.bundleIdentifier`) and enable **Push Notifications**.
|
|
17
|
+
2. Under Keys, create a key with **Apple Push Notifications service (APNs)** enabled. Download the `.p8` and note the Key ID and your Team ID. (A `.p12` APNs certificate also works, but certificates expire yearly.)
|
|
18
|
+
3. Choose `apsEnvironment` in the plugin config: `development` for dev builds, `production` for TestFlight and the App Store. The plugin writes the `aps-environment` entitlement and the `remote-notification` background mode — you don't edit Xcode by hand.
|
|
19
|
+
4. Test on a real device; the iOS simulator doesn't get APNs tokens reliably.
|
|
20
|
+
|
|
21
|
+
### Beams (Interests / Users only)
|
|
22
|
+
|
|
23
|
+
Create an instance in the [Pusher dashboard](https://dashboard.pusher.com/beams), upload the APNs key (with Key ID / Team ID) and the FCM service account JSON, and copy the instance ID. For the device-token path, skip this — your backend talks to FCM / APNs with those same credentials.
|
|
24
|
+
|
|
3
25
|
## Install
|
|
4
26
|
|
|
5
27
|
```sh
|
|
@@ -31,6 +53,8 @@ npx expo install expo-pusher-push-notifications
|
|
|
31
53
|
}
|
|
32
54
|
```
|
|
33
55
|
|
|
56
|
+
Leave out `instanceId` (and set `"mode": "device"`) if you use the device-token path.
|
|
57
|
+
|
|
34
58
|
Then run `npx expo prebuild` and build a development build. Expo Go cannot load this native module.
|
|
35
59
|
|
|
36
60
|
### Plugin options
|
|
@@ -47,11 +71,15 @@ Then run `npx expo prebuild` and build a development build. Expo Go cannot load
|
|
|
47
71
|
|
|
48
72
|
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.
|
|
49
73
|
|
|
50
|
-
##
|
|
74
|
+
## Start, per path
|
|
51
75
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
Pick one (Interests and Users can be combined).
|
|
77
|
+
|
|
78
|
+
| Path | Plugin config | First call |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| Interests | `instanceId` | `Interests.start(instanceId)` then `Interests.subscribe('news')` — see [Interests](interests.md) |
|
|
81
|
+
| Users | `instanceId`, `mode: "users"` | `Users.start(instanceId)` then `Users.login(userId, tokenProvider)` after sign-in — see [Users](users.md) |
|
|
82
|
+
| DeviceToken | `mode: "device"`, no `instanceId` | `DeviceToken.start()` → send `token` to your backend — see [Device token](direct.md) |
|
|
55
83
|
|
|
56
84
|
## Permissions
|
|
57
85
|
|
package/docs/users.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Bind a device to a user
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
> Before you start: finish the [Prerequisites](setup.md#prerequisites) (Firebase + APNs, plus a Beams instance).
|
|
3
5
|
Bind the device to the signed-in user so pushes for that user reach every device they're signed in on. Call `Users.login` after your own sign-in, and `Users.logout` on sign-out.
|
|
4
6
|
|
|
5
7
|
## In the app
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-pusher-push-notifications",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
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",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"files": [
|
|
68
68
|
"docs",
|
|
69
|
+
"skills",
|
|
69
70
|
"build",
|
|
70
71
|
"plugin/build",
|
|
71
72
|
"ios",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: migrate-from-b8ne
|
|
3
|
+
description: Migrate a React Native / Expo app from react-native-pusher-push-notifications (b8ne, ZeptInc, pusher-community forks) to expo-pusher-push-notifications 0.5.x. Use when an app imports react-native-pusher-push-notifications or has RNPusherPushNotifications native code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Migrate from react-native-pusher-push-notifications
|
|
7
|
+
|
|
8
|
+
Not a drop-in swap: callbacks become promises, init becomes `start()`, native code becomes an Expo config plugin. Full reference: `docs/migrating.md` in this package.
|
|
9
|
+
|
|
10
|
+
## Step 1 — Inventory (read-only)
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
rg -n "react-native-pusher-push-notifications|RNPusherPushNotifications" --glob '!node_modules'
|
|
14
|
+
rg -n "setInstanceId|setAppKey|setUserId|setSubscriptions|getSubscriptions|setOnSubscriptionsChangedListener|clearAllState" --glob '!node_modules' -t js -t ts
|
|
15
|
+
rg -n "PushNotifications|RNPusher|incrementBadge" ios android --glob '!Pods'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Record: instance ID source, interests used, whether users/`setUserId` is used, notification handler code, native files touched.
|
|
19
|
+
|
|
20
|
+
## Step 2 — Dependencies
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npm uninstall react-native-pusher-push-notifications # or yarn/pnpm equivalent
|
|
24
|
+
npx expo install expo-pusher-push-notifications
|
|
25
|
+
```
|
|
26
|
+
Bare RN without Expo modules: `npx install-expo-modules@latest` first. Expo Go is not supported (needs dev build).
|
|
27
|
+
|
|
28
|
+
## Step 3 — Native config
|
|
29
|
+
|
|
30
|
+
1. Add to `app.json`/`app.config.*` plugins: `["expo-pusher-push-notifications", { "instanceId": "<BEAMS_INSTANCE_ID>" }]`.
|
|
31
|
+
2. Ensure `expo.android.googleServicesFile` points at `google-services.json`.
|
|
32
|
+
3. If the project has committed `ios/`/`android/` (bare): delete `RNPusherPushNotifications` imports and calls in AppDelegate (`setDeviceToken`, `handleNotification`, didRegister/didReceive forwarding), Carthage/Pod entries for `PushNotifications` added manually, and Android `MainApplication`/manifest additions from the old README. Keep unrelated code.
|
|
33
|
+
4. Run `npx expo prebuild --clean` (managed) or `cd ios && pod install` (bare).
|
|
34
|
+
|
|
35
|
+
## Step 4 — JS rewrites
|
|
36
|
+
|
|
37
|
+
| Find | Replace with |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `import X from 'react-native-pusher-push-notifications'` | `import { Interests, Users, on, getInitialNotification } from 'expo-pusher-push-notifications'` |
|
|
40
|
+
| `X.setInstanceId(ID)` | `await Interests.start(ID)` (or `Users.start(ID)` if users are used) |
|
|
41
|
+
| `X.subscribe(i, onErr, onOk)` | `try { await Interests.subscribe(i); onOk?.() } catch (e) { onErr?.(e) }` |
|
|
42
|
+
| `X.unsubscribe(i, onErr, onOk)` | same pattern with `Interests.unsubscribe` |
|
|
43
|
+
| `X.setSubscriptions(arr)` | `await Interests.set(arr)` |
|
|
44
|
+
| `X.getSubscriptions(cb)` | `cb(await Interests.get())` |
|
|
45
|
+
| `X.setOnSubscriptionsChangedListener(cb)` | `on('subscriptionsChanged', cb)` |
|
|
46
|
+
| `X.setUserId(uid, token, onErr, onOk)` | `await Users.login(uid, token)` (prefer `{ url, headers }` token provider) |
|
|
47
|
+
| `X.clearAllState()` | `await Users.logout()` |
|
|
48
|
+
| `X.on('registered'\|'notification', cb)` | `const sub = on(...)`; remove `sub` on unmount |
|
|
49
|
+
|
|
50
|
+
Rules:
|
|
51
|
+
- Make enclosing functions `async` or use `.then/.catch`. Never leave a floating promise without error handling.
|
|
52
|
+
- Remove logic that waits for `'registered'` before subscribing; `start()` resolves when ready.
|
|
53
|
+
- Call `start` once (app root), before any subscribe/login.
|
|
54
|
+
- Android cold-start taps: add `getInitialNotification()` + `on('opened', ...)`.
|
|
55
|
+
- If `expo-notifications` or `@react-native-firebase/messaging` is installed for push, flag it to the user — conflict.
|
|
56
|
+
|
|
57
|
+
## Step 5 — Verify
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
rg -n "react-native-pusher-push-notifications|RNPusherPushNotifications" --glob '!node_modules' # expect no hits
|
|
61
|
+
npx tsc --noEmit
|
|
62
|
+
npx expo run:ios && npx expo run:android
|
|
63
|
+
```
|
|
64
|
+
Send a test push to an interest from the Beams dashboard on a real device; check foreground, background, and cold-start tap.
|
|
65
|
+
|
|
66
|
+
## Checklist
|
|
67
|
+
- [ ] Old package + native code removed
|
|
68
|
+
- [ ] Plugin added with instanceId; googleServicesFile set; prebuild run
|
|
69
|
+
- [ ] All callbacks converted to promises with error handling
|
|
70
|
+
- [ ] Listeners return subscriptions that are removed
|
|
71
|
+
- [ ] Users flow: login after sign-in, logout on sign-out
|
|
72
|
+
- [ ] Typecheck passes; test push received on both platforms
|
|
73
|
+
- [ ] Summarize changes and any manual console steps (APNs key, Firebase) for the user
|