Web Push and Expo Push
The app supports web push (browser) and Expo push (mobile) so users receive chat and call notifications when the tab or app is in the background. Both flows use the same backend pipeline: the API publishes chat/call events to RabbitMQ, and dedicated workers consume and send push to the recipient.
Overview
| Channel | Worker | Purpose |
|---|---|---|
| Web Push (browser) | WebPushNotificationWorker | Sends push to browser (Chrome, Firefox, etc.) via Web Push API; user subscribes in Settings → Notification. |
| Expo Push (mobile) | ExpoPushNotificationWorker | Sends push to mobile app via Expo Push Service; app registers Expo token with the API after login. |
Both workers consume the same messages from RabbitMQ (ChatMessage, IncomingCallPushMessage), so when someone sends a chat message or starts a call, the appropriate worker sends a push to the recipient’s device(s).
What Must Be Running
For chat/call push to be delivered:
| Service | Purpose |
|---|---|
| RabbitMQ | Message broker; API publishes chat/call events here; workers consume from here. |
| API | When a user sends a message (or starts a call), API publishes to RabbitMQ; also stores push subscriptions (web) and Expo tokens (mobile). |
| MongoDB | API and workers use it (subscriptions and tokens). |
| WebPushNotificationWorker | Consumes from RabbitMQ and sends web push to recipient’s browser. |
| ExpoPushNotificationWorker | Consumes from RabbitMQ and sends push to recipient’s mobile app via Expo. |
If a worker shows “Bus started” but no push is received, ensure the API is running when the message or call is sent (the API publishes to RabbitMQ).
Web Push (browser)
User flow
- User logs in and goes to Settings → Notification.
- User clicks Enable notifications and allows the browser permission.
- The frontend registers the push subscription with the API (
POST /api/push-subscriptions). - When someone sends a chat message or starts a call, the API publishes to RabbitMQ; WebPushNotificationWorker consumes and sends a web push to the recipient’s browser.
- The recipient sees an OS/browser notification (e.g. “Someone: message preview” or incoming call).
Test notification (no worker)
The API can send a test push directly (no RabbitMQ/worker):
- In the app: Settings → Notification → Send test notification.
- Or call
POST /api/push-subscriptions/testwith a valid JWT.
This verifies subscription and permission; real chat/call push still requires the worker and RabbitMQ.
API endpoints (web push)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/push-subscriptions | Register a push subscription (endpoint, p256dh, auth). |
| DELETE | /api/push-subscriptions | Unregister by endpoint. |
| POST | /api/push-subscriptions/renew | Renew subscription (e.g. after pushsubscriptionchange). |
| GET | /api/push-subscriptions | List current user’s subscriptions. |
| POST | /api/push-subscriptions/test | Send a test push (API sends directly). |
Run WebPushNotificationWorker
cd Src/backend/WebPushNotificationWorker
dotnet run
Use the same RabbitMQ and MongoDB (and WebPush VAPID keys) as in the API’s appsettings.Development.json.
Expo Push (mobile)
Expo push is ready. The mobile app (Expo / React Native) obtains an Expo push token and injects it into the WebView; the frontend inside the WebView registers the token with the API. The ExpoPushNotificationWorker and API endpoints send chat and call pushes to the device when the app is in the background. See Mobile App for architecture and run instructions. Later: deep linking when the user taps a notification and EAS Build for production IPA/APK.
User flow
- User opens the mobile app and loads the frontend in the WebView (after entering the frontend URL once).
- The app requests notification permission and obtains an Expo push token.
- The app injects the token into the WebView; the frontend listens for
EXPO_PUSH_TOKENand registers it with the API (POST /api/push-subscriptions/expo). - When someone sends a chat message or starts a call, the API publishes to RabbitMQ; ExpoPushNotificationWorker consumes and sends push via Expo’s service to the recipient’s device.
- The recipient sees an OS notification (e.g. “Someone: message preview” or incoming call).
API endpoints (Expo push)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/push-subscriptions/expo | Register an Expo push token for the current user. |
| DELETE | /api/push-subscriptions/expo | Unregister Expo token (e.g. by token or device). |
Run ExpoPushNotificationWorker
cd Src/backend/ExpoPushNotificationWorker
dotnet run
Use the same RabbitMQ and MongoDB as the API.
Message flow (chat / call push)
- User A sends a message to User B (or starts a call to User B).
- API saves the message/call and publishes
ChatMessage(orIncomingCallPushMessage) to RabbitMQ. - WebPushNotificationWorker consumes the message and, if User B has web push subscriptions, sends a web push to each.
- ExpoPushNotificationWorker consumes the same message and, if User B has Expo tokens, sends push via Expo to each device.
- User B sees an OS notification (browser and/or mobile) when the tab/app is in the background.
Worker logs to look for:
- Web:
WebPush: Consuming chat message ...andWebPush: Sent chat push for message ... - Expo:
ExpoPush: Consuming chat message ...andExpoPush: Sent chat push for message ...
Configuration
Web Push (VAPID)
Configure in API and WebPushNotificationWorker (e.g. appsettings.json or appsettings.Development.json):
{
"WebPush": {
"PublicKey": "your-vapid-public-key",
"PrivateKey": "your-vapid-private-key"
}
}
The frontend needs the same PublicKey (e.g. VITE_VAPID_PUBLIC_KEY).
RabbitMQ and MongoDB
Workers must use the same RabbitMQ (host, vhost, credentials) and MongoDB (connection string, database name) as the API so they consume the same messages and read the same subscription/token data.
Troubleshooting
- Test notification works but chat/call push does not: Ensure RabbitMQ and the relevant worker (WebPushNotificationWorker and/or ExpoPushNotificationWorker) are running when the message or call is sent.
- Worker shows “Bus started” but no “Consuming chat message”: The API must be running when the sender submits the message; the API publishes to RabbitMQ.
- Web: no notification on Mac/Windows: Check OS notification settings for the browser (e.g. System Settings → Notifications → your browser → Allow). Allow notifications for the site in the browser (e.g. site settings for
localhostor your domain). Try sending the test with the tab in the background. - Expo: no notification on device: Ensure the app registered the Expo token with the API after login and that the device allows notifications for the app.
Related
- Mobile App – Expo shell, WebView, and Expo push token injection.
- Notifications Feature – In-app and real-time notifications (SignalR).
- Messaging Feature – Chat and call APIs and real-time behavior.
- Workers Architecture – WebPushNotificationWorker and ExpoPushNotificationWorker.