Skip to content

Commit 04807b0

Browse files
abueideclaude
andcommitted
fix(amplitude-session): recover lastEventTime on partial persist
Replace incorrect 1-second timestamp guard with proper root cause fix. The 0-second session bug is caused by non-atomic AsyncStorage persistence: when the app is killed (e.g. during iOS Background Fetch), sessionId may persist while lastEventTime does not. On relaunch, lastEventTime === -1 with a valid sessionId falsely triggers session expiration, ending the just-created session immediately. The fix recovers lastEventTime from sessionId when partial persistence is detected, preventing the false expiration. Also adds hypothesis-driven reproduction tests that verify the fix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ada90d2 commit 04807b0

2 files changed

Lines changed: 472 additions & 47 deletions

File tree

packages/plugins/plugin-amplitudeSession/src/AmplitudeSessionPlugin.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,6 @@ export class AmplitudeSessionPlugin extends EventPlugin {
207207
};
208208

209209
private onForeground = () => {
210-
// Guard against rapid session creation from iOS Background Fetch.
211-
// iOS can briefly trigger AppState 'active' during background tasks,
212-
// causing 0-second sessions from rapid foreground/background cycles.
213-
const now = Date.now();
214-
if (this.sessionId > 0 && now - this.sessionId < 1000) {
215-
return;
216-
}
217210
this.startNewSessionIfNecessary();
218211
};
219212

@@ -226,11 +219,18 @@ export class AmplitudeSessionPlugin extends EventPlugin {
226219
return;
227220
}
228221

222+
// If lastEventTime was lost but sessionId is valid (partial persistence
223+
// failure, e.g. app killed before all AsyncStorage writes complete),
224+
// recover lastEventTime from sessionId to avoid falsely expiring the session.
225+
if (this.lastEventTime === -1 && this.sessionId >= 0) {
226+
this.lastEventTime = this.sessionId;
227+
}
228+
229229
const current = Date.now();
230230
const withinSessionLimit = this.withinMinSessionTime(current);
231231

232232
const isSessionExpired =
233-
this.sessionId === -1 || this.lastEventTime === -1 || !withinSessionLimit;
233+
this.sessionId === -1 || !withinSessionLimit;
234234

235235
if (this.sessionId >= 0 && !isSessionExpired) {
236236
return;

0 commit comments

Comments
 (0)