Skip to content

Show stored snackbar notices once, not again after a relaunch - #81

Merged
dadachi merged 1 commit into
mainfrom
fix/stale-stored-notice-snackbar
Oct 13, 2026
Merged

dadachi merged 1 commit into
mainfrom
fix/stale-stored-notice-snackbar

Conversation

@dadachi

@dadachi dadachi commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Bug

After a shop is deleted (which restarts the app), closing or force-stopping the app while the "Shop removed." snackbar is still up made it show again at every launch.

NativeAppTemplateApp showed each notice stored in DataStore (isShopDeleted, isEmailUpdated, isMyAccountDeleted) in a LaunchedEffect keyed on the flag. It cleared the flag only after the Indefinite snackbar returned, i.e. after the shopkeeper dismissed it. The paid app has the same bug, found with "Switched organization": nativeapptemplate/NativeAppTemplate-Android#115.

Fix

New ui/app_root/StoredNotice.kt:

  • The flag is cleared as soon as the notice is taken for display, before the snackbar is shown. The effects collect the flag (keyed on appState) instead of being keyed on it, so clearing it does not cancel the snackbar.
  • showStoredNotice (collects while the app runs) is used for the sign-out notices (isEmailUpdated, isMyAccountDeleted), which the same process shows.
  • showNoticeStoredForLaunch (reads the flag once at launch) is used for isShopDeleted, which is stored just before restartApp(). With live collection, the process that stored the flag would take it, clear it and start the snackbar right before it exits, so the restarted app would not show it. This was seen on device in the paid app.
  • The unused isEmailUpdated/isMyAccountDeleted/isShopDeleted state flows are removed from NativeAppTemplateAppState, along with their test (deletionFlags_comeFromThePreferences). The effects read the DataStore flows directly, because first() on a stateIn flow would return its initial false.

Tests

StoredNoticeTest simulates app processes against one InMemoryDataStore, which plays the role of the DataStore file that outlives the process. Cancelling a launch means the process ended with the snackbar still up.

  • shopDeleted_isShownOnceByTheRestartedApp_evenIfItIsClosedWhileTheNoticeShows
  • emailUpdated_isShownOnceByTheRunningApp_evenIfItIsClosedWhileTheNoticeShows
  • emailUpdated_storedAgain_isShownAgain

Seen red:

  • showNoticeStoredForLaunch with show-then-clear (the original order): expected:<1> but was:<2>. With live collection: expected:<0> but was:<1>.
  • showStoredNotice with show-then-clear: expected:<1> but was:<2>.

Local checks

./scripts/pre-push passes: spotlessCheck, lintDebug, :app:minifyReleaseWithR8 and test. 409 test cases, 0 failures.

Device check (Pixel, local API, shopkeeper1)

  • main: created and deleted a throwaway shop. After force-stop and relaunch without dismissing, "Shop removed." showed again on both relaunches (reproduced).
  • This branch:
    • The flag left set by main showed once, then not again on the next 2 relaunches.
    • Creating and deleting another throwaway shop showed "Shop removed." once after the restart, then not after force-stop and relaunch (×2).
  • Both throwaway shops were deleted.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH

The app root showed the notices stored in DataStore (shop deleted, email
changed, account deleted) in a LaunchedEffect keyed on the flag, and cleared
the flag only after the Indefinite snackbar was dismissed. Closing the app while
the snackbar was up left the flag set, so "Shop removed." came back at every
launch.

The flag is now cleared as soon as the notice is taken for display, in a
collected effect so clearing it does not cancel the snackbar. The shop-deleted
notice, stored just before the app restarts itself, is read once at launch: the
process that stored it would otherwise take the flag and lose the snackbar a
moment later when it exits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH
@dadachi
dadachi merged commit 245d8c9 into main Oct 13, 2026
1 check passed
@dadachi
dadachi deleted the fix/stale-stored-notice-snackbar branch October 15, 2026 05:30
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