Skip to content

Fixed: stop persisting the Firebase session flag - #165

Closed
dt2patel wants to merge 1 commit into
mainfrom
fix/notification-session-flag-not-persisted
Closed

dt2patel wants to merge 1 commit into
mainfrom
fix/notification-session-flag-not-persisted

Conversation

@dt2patel

Copy link
Copy Markdown
Contributor

The bug

isFirebaseInitialised records whether the Firebase SDK was initialised in the current page context. The SDK does not survive a reload. A persisted flag does.

So after any reload the flag rehydrates as true against a freshly empty SDK, initialiseFirebaseMessaging takes its early return, and the app ends up with:

  • no onMessage handler, so no foreground notifications
  • no BroadcastChannel listener, so background notifications never reach the in-app bell
  • no registration token posted

while still reporting itself as initialised. The service worker keeps drawing OS banners independently, so from the outside it looks like "notifications sort of work but the bell is always empty", which is exactly what was reported from the field.

This is not a rare edge case. VitePWA({ registerType: "autoUpdate" }) reloads the app without asking, so a store tablet reaches this state on its own. It also silently defeats token-refresh work, because that path sits behind the same guard.

The fix

One field excluded from persistence. It is session state, not user data.

omit is applied on hydration as well as on write (hydrateStore, before $patch), so devices that already hold the flag from an earlier build have it ignored on their next load. No storage reset or app reinstall is needed to recover them.

Verified, not assumed

Exercised in a real browser against the real store definition, not a mock:

result
Still writes persisted state yes
isFirebaseInitialised written no
firebaseDeviceId survives yes
allNotificationPrefs survives yes
Flag still works in memory within a session yes

I tried to add a unit test first and could not make one that proves anything here. The persistence plugin does not run under this workspace's vitest setup at all: jsdom provides no Storage, and with an in-memory stand-in neither persist: true nor persist: { omit } writes anything. Rather than land a test that passes without exercising the behaviour, I verified in a browser and am saying so plainly. If someone knows how persistence is meant to be tested here, a regression test would be worth adding.

Blast radius

common is shared, so this affects every app that uses the notification store (BOPIS, fulfillment, receiving). The change is safe for all of them: any app relying on this flag surviving a reload was already broken, because the SDK it refers to does not survive either.

Note for deployment: app repos resolve @common by path into an accxui checkout, so a BOPIS build only picks this up once its build uses an accxui containing it.

🤖 Generated with Claude Code

isFirebaseInitialised records whether the Firebase SDK was initialised
in the current page context. The SDK does not survive a reload, but a
persisted flag does, so after any reload the flag rehydrated as true
against a freshly empty SDK. Every caller then took the early return in
initialiseFirebaseMessaging and the app ended up with no onMessage
handler, no background message listener and no registration token, while
still reporting itself as initialised.

This is not a rare edge case. VitePWA is configured with
registerType "autoUpdate", so a store device reloads without being
asked and reaches this state on its own. It also silently defeats any
token refresh work, because the refresh path is behind the same guard.

The flag is session state rather than user data, so it is excluded from
persistence. The plugin applies omit on hydration as well as on write,
so devices that already hold the flag from an earlier build have it
ignored on their next load and need no storage reset.

Verified in a browser against the real store: persistence still writes
firebaseDeviceId, allNotificationPrefs, notificationPrefs, notifications
and hasUnreadNotifications, and no longer writes isFirebaseInitialised,
while the flag continues to work in memory within a session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-16T11:33:35.499612Z f111eaa PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@dt2patel dt2patel closed this Sep 27, 2026
@dt2patel
dt2patel deleted the fix/notification-session-flag-not-persisted branch September 27, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant