Push Notification Deep Link Fails After the App Is Killed
Metro Support's OutSystems mobile app notifies technicians when a ticket is assigned. The push payload includes TicketId. Tapping a notification opens TicketDetail when the app is in the background, but when the app has been killed it lands on the home screen. The notification handler writes TicketId to a Session Variable and immediately calls Navigate. On a cold start the handler runs before the app's entry screen finishes loading, so the navigation is dropped. On iOS, notifications stop after an app update because the device token changes; the server entity still holds the old token. About 30% of notification taps fail. The team wants one path that handles cold and warm starts, avoids opening the same ticket twice, and keeps working after app updates. Support technicians often tap several notifications in a row while walking between floors.
1. Explain why the cold-start tap is lost and design a routing mechanism that works for both cold and warm starts.
Read the worked answer
The handler is assuming the app is already navigable. On a cold start, the notification callback can fire before the entry screen and navigation stack exist. Calling Navigate at that moment has no valid target, so the call is ignored. In the warm case the app is already on a screen, so the same code appears to work, which hides the ordering bug.
The fix is to separate 'receive' from 'route'. The handler should persist a pending deep link, for example in local storage with NotificationId, TicketId, and received time, and return immediately. A single consumer in the app's startup flow checks the pending queue after the entry screen is ready and navigates once. The same consumer also runs on resume so warm taps follow the same path. Clear the pending item only after navigation succeeds, and keep a last-processed NotificationId to suppress duplicates when the OS delivers the same tap twice.
Do not use a Session Variable as the handoff, because it is not a durable queue and its lifetime does not match the cold-start ordering. Persist the intent, then route it when the app is ready.
2. How should Metro Support manage device tokens so notifications survive app updates, especially on iOS?
Read the worked answer
Treat the token as volatile device state, not as a fixed user attribute. Register or refresh the token every time the app starts and whenever the push plugin reports a token refresh. Send the token, platform, app version, device identifier, and user ID to the server, and upsert by token so one device does not accumulate duplicate active rows.
On iOS, an app update or restore can produce a new token. The server must deactivate the previous token for that device/user pair when the new one arrives, and it must handle delivery failures that indicate an invalid token by marking it inactive rather than retrying forever. Keep a history only for audit; do not keep sending to old tokens.
Also verify the notification payload after an update, because the app version and plugin version can change together. Test the full path: install, receive, update app, receive again, tap from killed state. A token refresh alone will not fix the cold-start routing bug, so the two fixes must be validated together.
3. A technician taps three notifications in a row while walking. What sequencing rules prevent duplicate or out-of-order ticket screens?
Read the worked answer
Use a single-consumer queue with explicit ordering and de-duplication. Each notification gets a unique NotificationId and a received timestamp. When a tap arrives, enqueue it if it is not already the last processed ID. The consumer processes one item at a time: navigate to the ticket, wait for the screen to become ready, then mark it consumed. If a newer tap arrives while an older one is being processed, do not navigate immediately; replace or append in the queue according to the product rule.
The product rule should be stated. For support, 'latest tap wins' is usually right: the technician tapped the most recent alert last. Implement that by keeping only the newest pending item for the same technician, while retaining the IDs for audit. If different tickets are involved, process the latest and discard older pending taps to avoid a navigation storm.
Finally, guard against duplicate screens by checking whether the target ticket is already the top of the navigation stack before pushing a new instance. Clear the pending item only after the guard passes. Log every tap, enqueue, and navigation result so the 30% failure rate can be measured rather than guessed.