RocketChat / RocketChat/Rocket.Chat.ReactNative
[iOS] Stale video conference notification re-dispatched on every cold boot due to missing deduplication
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 1.5k
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 90
Description
On iOS, when a user taps "Accept" or "Decline" on a video conference push notification, the app correctly processes the action. However, Expo’s getLastNotificationResponseAsync() / getLastNotificationResponse() does not clear the last notification response after it is read.
Because of this, the same stale notification persists across cold boots (force-close → reopen from app icon). Every time the app launches normally, it re-processes the old video conference notification and dispatches deepLinkingClickCallPush again.
This causes users to be repeatedly forced into an old, already-ended video call.
Root Cause
There is no deduplication logic in the notification handling pipeline.
- No notification ID is stored after processing.
- No check exists to verify whether a notification has already been handled.
- Expo persists the last notification response across cold boots by design.
As a result, the same notification is dispatched repeatedly.
Affected Code Paths
Path 1
app/lib/notifications/push.ts (around line 277)
- Calls
Notifications.getLastNotificationResponse() - Immediately returns the transformed notification
- No ID check
Flows into:
app/lib/notifications/index.ts (lines 42–44)
- If
notificationType === 'videoconf' - Immediately dispatches
deepLinkingClickCallPush - No deduplication check
Path 2 (Backup Path)
app/lib/notifications/videoConf/getInitialNotification.ts (lines 56–75)
- Calls
getLastNotificationResponseAsync() - Parses ejson
- If
notificationType === 'videoconf' - Immediately dispatches
deepLinkingClickCallPush - No deduplication check
Saga Handler
app/sagas/deepLinking.js (handleClickCallPush)
- No staleness check
- No timestamp validation
- Attempts to join any video call regardless of age
Environment
- Rocket.Chat Server Version: Any
- Rocket.Chat App Version: Latest (develop branch)
- Device: Any iOS device
- OS Version: iOS 15+
Steps to Reproduce
- Receive a video conference push notification on iOS.
- Long-press the notification and tap Accept.
- App opens and joins the call.
- End the call.
- Force-close the app.
- Wait any amount of time.
- Reopen the app normally (tap app icon).
Observed Result
- The app attempts to join the same old, ended video call.
- Force-close and reopen again → same behavior.
- This repeats indefinitely until another notification is tapped.
Expected Behavior
When opening the app normally (not from a notification):
- App should open to the home screen or last viewed room.
- A previously processed video conference notification should never be re-processed.
Actual Behavior
Every cold boot re-processes the same stale video conference notification and dispatches deepLinkingClickCallPush, forcing the user into an old call.
This continues indefinitely until a new notification interaction replaces the stored response.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Trace the notification flow through app/lib/notifications/push.ts, app/lib/notifications/index.ts, and app/lib/notifications/videoConf/getInitialNotification.ts, then inspect handleClickCallPush in app/sagas/deepLinking.js. Reproduce the cold-boot behavior on iOS and identify how both paths process the persisted response. Done means a previously handled video conference response is not dispatched again after force-close and normal relaunch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, react-native, typescript
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100