@fishonfire/bubbles-expo 0.1.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/LICENSE +674 -0
- package/README.md +180 -0
- package/app.plugin.js +1 -0
- package/dist/chunk-6NPXFGQX.mjs +1308 -0
- package/dist/index.d.mts +306 -0
- package/dist/index.d.ts +306 -0
- package/dist/index.js +2060 -0
- package/dist/index.mjs +789 -0
- package/dist/register-task.d.mts +2 -0
- package/dist/register-task.d.ts +2 -0
- package/dist/register-task.js +818 -0
- package/dist/register-task.mjs +6 -0
- package/package.json +94 -0
- package/plugin/build/config.d.ts +18 -0
- package/plugin/build/config.js +69 -0
- package/plugin/build/index.d.ts +4 -0
- package/plugin/build/index.js +19 -0
- package/plugin/build/shared-config.d.ts +3 -0
- package/plugin/build/shared-config.js +11 -0
- package/plugin/build/with-expo-notifications.d.ts +3 -0
- package/plugin/build/with-expo-notifications.js +19 -0
- package/plugin/build/with-firebase-messaging-manifest.d.ts +4 -0
- package/plugin/build/with-firebase-messaging-manifest.js +35 -0
- package/plugin/build/with-rnfirebase-disable-spm.d.ts +3 -0
- package/plugin/build/with-rnfirebase-disable-spm.js +14 -0
- package/plugin/build/with-runtime-defaults.d.ts +3 -0
- package/plugin/build/with-runtime-defaults.js +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# @fishonfire/bubbles-expo
|
|
2
|
+
|
|
3
|
+
`@fishonfire/bubbles-expo` is an Expo package for integrating Bubbles push notifications into an Expo app.
|
|
4
|
+
|
|
5
|
+
It provides:
|
|
6
|
+
|
|
7
|
+
- an Expo config plugin for notification setup
|
|
8
|
+
- an explicit background registration API for Firebase notification handling
|
|
9
|
+
- a React provider and hook for Bubbles device registration and notification responses
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @fishonfire/bubbles-expo
|
|
15
|
+
npx expo install expo-notifications @react-native-firebase/app @react-native-firebase/installations @react-native-firebase/messaging
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Add your Firebase service files to Expo config:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"expo": {
|
|
23
|
+
"android": {
|
|
24
|
+
"googleServicesFile": "./google-services.json"
|
|
25
|
+
},
|
|
26
|
+
"ios": {
|
|
27
|
+
"googleServicesFile": "./GoogleService-Info.plist"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Use a development build or release build for push notification testing. Expo Go does not include the required native Firebase modules.
|
|
34
|
+
For iOS, also complete Firebase Messaging and APNs setup in the consuming app.
|
|
35
|
+
|
|
36
|
+
## Configure the plugin
|
|
37
|
+
|
|
38
|
+
Add the required plugins in `app.json` or `app.config.ts`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"expo": {
|
|
43
|
+
"plugins": [
|
|
44
|
+
"@react-native-firebase/app",
|
|
45
|
+
"@react-native-firebase/messaging",
|
|
46
|
+
[
|
|
47
|
+
"@fishonfire/bubbles-expo",
|
|
48
|
+
{
|
|
49
|
+
"defaultChannelId": "default",
|
|
50
|
+
"defaultChannelName": "Default",
|
|
51
|
+
"androidChannelImportance": "max",
|
|
52
|
+
"androidNotificationIcon": "./assets/notification-icon.png",
|
|
53
|
+
"androidNotificationColor": "#208AEF",
|
|
54
|
+
"enableBackgroundRemoteNotifications": true
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Plugin options:
|
|
63
|
+
|
|
64
|
+
- `defaultChannelId`: Android default notification channel id. Default: `"default"`.
|
|
65
|
+
- `defaultChannelName`: Android default notification channel name. Default: `"Default"`.
|
|
66
|
+
- `androidChannelImportance`: Android channel importance. One of `min`, `low`, `default`, `high`, or `max`. Default: `"max"`.
|
|
67
|
+
- `androidNotificationIcon`: Optional Android notification icon path.
|
|
68
|
+
- `androidNotificationColor`: Optional Android notification color in `#RRGGBB` or `#AARRGGBB` format.
|
|
69
|
+
- `enableBackgroundRemoteNotifications`: Passed through to `expo-notifications`. Default: `true`.
|
|
70
|
+
|
|
71
|
+
For Android remote display, backend payloads must use the same `android.notification.channel_id` as `defaultChannelId`. The plugin writes Firebase's default-channel manifest metadata, and the package creates the actual Android notification channel when `BubblesNotificationsProvider`, `getNotificationPermissions()`, or `ensureDefaultNotificationChannel()` runs. On a fresh install, the app must be opened at least once before remote notifications can reliably use this configured channel; otherwise Android/Firebase may fall back to its own default behavior before JavaScript has created the channel.
|
|
72
|
+
|
|
73
|
+
## Background registration
|
|
74
|
+
|
|
75
|
+
Register the package-owned background notification handlers once from your app entrypoint:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { registerBubblesBackgroundHandlers } from '@fishonfire/bubbles-expo';
|
|
79
|
+
|
|
80
|
+
registerBubblesBackgroundHandlers();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Do this as early as possible, especially if your app loads notification UI lazily. `BubblesNotificationsProvider` does not register background handlers for you.
|
|
84
|
+
|
|
85
|
+
The registered background path uses React Native Firebase for remote delivery and is intended for silent/data processing plus Android data-only local presentation when your product explicitly supports it. It is not the delivery mechanism for normal visible iOS notifications. User-visible iOS pushes must use the normal visible payload with APNs alert fields so the OS can display them while the app is backgrounded or terminated.
|
|
86
|
+
|
|
87
|
+
`expo-notifications` still owns local presentation, permissions, channels, and response handling.
|
|
88
|
+
|
|
89
|
+
If you prefer a side-effect-only bootstrap module, the compatibility entrypoint is still available:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import '@fishonfire/bubbles-expo/register-task';
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Only use the compatibility entrypoint once, from the app entrypoint or another module imported by the entrypoint. Do not wait for React providers, navigation, or authenticated app state before registering background handlers.
|
|
96
|
+
|
|
97
|
+
## Wrap your app
|
|
98
|
+
|
|
99
|
+
Wrap your app with `BubblesNotificationsProvider`:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import {
|
|
103
|
+
BubblesNotificationsProvider,
|
|
104
|
+
type BubblesNotificationResponseEvent,
|
|
105
|
+
} from '@fishonfire/bubbles-expo';
|
|
106
|
+
import { router, type Href } from 'expo-router';
|
|
107
|
+
|
|
108
|
+
function handleNotificationResponse(event: BubblesNotificationResponseEvent) {
|
|
109
|
+
if (event.url) {
|
|
110
|
+
router.push(event.url as Href);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function AppProviders({
|
|
115
|
+
children,
|
|
116
|
+
}: {
|
|
117
|
+
children: React.ReactNode;
|
|
118
|
+
}) {
|
|
119
|
+
return (
|
|
120
|
+
<BubblesNotificationsProvider
|
|
121
|
+
appId="your-app-id"
|
|
122
|
+
appKey="your-app-key"
|
|
123
|
+
apiBaseUrl="https://api.example.com"
|
|
124
|
+
ready={true}
|
|
125
|
+
userId="current-user-id"
|
|
126
|
+
aliasing={['customer-123']}
|
|
127
|
+
onNotificationResponse={handleNotificationResponse}>
|
|
128
|
+
{children}
|
|
129
|
+
</BubblesNotificationsProvider>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Required provider props:
|
|
135
|
+
|
|
136
|
+
- `appId`: Bubbles app id.
|
|
137
|
+
- `appKey`: Bubbles app key used to verify the configured app id.
|
|
138
|
+
- `apiBaseUrl`: Bubbles API base URL.
|
|
139
|
+
- `ready`: Set to `true` when auth and app state are ready for registration.
|
|
140
|
+
- `userId`: Current signed-in user id, or `null` when signed out.
|
|
141
|
+
|
|
142
|
+
## Register the device
|
|
143
|
+
|
|
144
|
+
Call `registerDevice()` when the app is ready and the user is signed in:
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
import { Button } from 'react-native';
|
|
148
|
+
import { useBubblesNotifications } from '@fishonfire/bubbles-expo';
|
|
149
|
+
|
|
150
|
+
export function EnableNotificationsButton() {
|
|
151
|
+
const { registerDevice, isSyncing } = useBubblesNotifications();
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<Button
|
|
155
|
+
title="Enable notifications"
|
|
156
|
+
disabled={isSyncing}
|
|
157
|
+
onPress={() => {
|
|
158
|
+
void registerDevice();
|
|
159
|
+
}}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`useBubblesNotifications()` also exposes `deviceId`, `pushToken`, `permissionStatus`, `notificationsEnabled`, `tokenType`, and `error`.
|
|
166
|
+
|
|
167
|
+
If your app already requested notification permissions, call `registerDevice({ requestPermissions: false })`.
|
|
168
|
+
|
|
169
|
+
## Example application
|
|
170
|
+
A example application can be found at: https://github.com/fishonfire/bubbles-notifications-expo-example
|
|
171
|
+
|
|
172
|
+
## Contributors
|
|
173
|
+
- Simon de la Court (https://github.com/simondelacourt)
|
|
174
|
+
- Jan Deen (https://github.com/Jan-F15H)
|
|
175
|
+
- Menno Jongejan (https://github.com/mennolpFoF)
|
|
176
|
+
|
|
177
|
+
## Copyright and Licence
|
|
178
|
+
Copyright (c) 2026, Fish on Fire.
|
|
179
|
+
|
|
180
|
+
Source code is licensed under the [`GPL License`](https://github.com/fishonfire/bubbles-notifications-expo/blob/develop/LICENSE).
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./plugin/build');
|