Repository navigation
[Bug]: Push-to-start Live Activity never gets its update token when the app was swiped away (token arrives before setup's activity observer attaches) #1784
Description
What happened?
We start a Live Activity with the REST push-to-start API (DefaultLiveActivityAttributes, OneSignal.LiveActivities.setupDefault() called natively in didFinishLaunchingWithOptions). When the app had been swiped away from the app switcher, the activity appears, but every later update and end for that activity_id is delivered to 0 iOS recipients. The card stays on its first state until iOS expires it.
When the app is only backgrounded (still in memory), the same flow works: the update token is registered and both the update and the end are delivered.
The device log from the swiped-away case shows that iOS does relaunch the app in the background and hands the process the new activity's update token. That happens about 1 ms before the SDK's per-activity pushTokenUpdates observer is attached. The observer then logs "Push token is not available; waiting for next update", and no token is ever emitted to it, so enter is never called:
14:28:44.276840 liveactivitiesd Starting activity: id: 0E4D6F2A-…
14:28:45.093737 liveactivitiesd Received app token with identifier: 0E4D6F2A-… for environment: development
14:28:45.574950 <App>(ActivityKit) Activated ActivityPushTokenClient connection
14:28:45.584030 <App>(ActivityKit) Push token is not available; waiting for next update
14:28:45.585434 <App>(ActivityKit) [DefaultLiveActivityAttributes] Creating activity: 0E4D6F2A-…
14:28:45.595441 <App>(ActivityKit) Push tokens changed: ["0E4D6F2A-…": 80 bytes, "<bundle>::pushToStart": 80 bytes]
14:28:45.596828 <App>(ActivityKit) Push token is not available; waiting for next update
(no "Emitting push token" for 0E4D6F2A afterwards; the app is suspended)
The backgrounded run on the same device logs "Push tokens changed" after the activity observer exists, and then emits the token normally.
Our reading is that the order inside setup/setupDefault matters on a cold background launch. Opening the token connection (push-to-start listener) makes ActivityKit flush pending tokens immediately. A pushTokenUpdates sequence created a moment later does not replay the current token. Reading activity.pushToken when the observer attaches, or attaching the activity observers before the push-to-start listener, would likely close the gap. We haven't verified either.
This may compound with #1769: even when the token is received during the background wake, its upload is a single attempt with no background task.
Steps to reproduce?
- Integrate with
OneSignal.LiveActivities.setupDefault()inAppDelegate.didFinishLaunchingWithOptions, log in a user, and allow Live Activities. - Swipe the app away in the app switcher and lock the device.
- Start an activity via
POST /apps/{app_id}/activities/activity/DefaultLiveActivityAttributes(push-to-start,include_aliases.external_id). - About 60 s later, send an update via
POST /apps/{app_id}/live_activities/{activity_id}/notifications(event: update), then an end. - The start is delivered. The update and end report 0 iOS recipients, and the card never changes.
Control: repeat with the app only backgrounded (Home button, not swiped). The update and end are delivered.
What did you expect to happen?
The SDK registers the update token for an activity started by push-to-start whenever iOS relaunches the app in the background, so updates and ends reach the activity even when the app was not running.
OneSignal iOS SDK version
OneSignalXCFramework 5.8.0, via react-native-onesignal 5.5.15. It was also reproduced on 5.2.10.
iOS version
iOS 27.0 on an iPhone 16, Release build with development APNs. It was also reproduced on the iOS 27.0 simulator.
Reproduction rate
Every terminated-app run we tried: 2 on the device (swiped away, and killed via devicectl) and 3 on the simulator (simctl terminate). None delivered the update or the end.
Relevant log output
See the excerpt above. A full liveactivitiesd/ActivityKit log for both runs is available on request.
Code of Conduct
- I agree to follow this project's Code of Conduct
Activity