Skip to content

fix(messaging): resolve getToken() when observed service worker becomes redundant - #10246

Open
chan-mai wants to merge 2 commits into
firebase:mainfrom
chan-mai:fix/messaging-sw-registration-redundant
Open

fix(messaging): resolve getToken() when observed service worker becomes redundant#10246
chan-mai wants to merge 2 commits into
firebase:mainfrom
chan-mai:fix/messaging-sw-registration-redundant

Conversation

@chan-mai

@chan-mai chan-mai commented Aug 1, 2026

Copy link
Copy Markdown

Discussion

Fixes #10197.

getToken() intermittently fails with:

Messaging: We are unable to register the default service worker. Service worker not registered after 10000 ms (messaging/failed-service-worker-registration).

even though the service worker registers and activates successfully.

Root cause

waitForRegistrationActive (added in #8661) captures a single worker
(registration.installing || registration.waiting) at call time and resolves
only when that specific worker fires statechange'activated'.

registerDefaultSw calls registration.update() immediately before awaiting
waitForRegistrationActive. When that update installs a replacement worker —
common right after a redeploy, when the SW script or one of its
importScripts dependencies changed — the originally observed worker
transitions to 'redundant' and never fires 'activated'. The promise then
hangs until the 10s timeout, even though the replacement worker activates
successfully in the meantime. The 'redundant' transition is never handled,
so the call can neither recover nor fail fast.

Fix

waitForRegistrationActive now:

  1. resolves as soon as registration.active is set, regardless of which
    specific worker reached the 'activated' state;
  2. follows replacement workers via the registration's updatefound event; and
  3. re-attaches to the next incoming worker when the one it was watching
    becomes 'redundant'.

All listeners and the timeout are cleaned up once the promise settles.

This also removes the previous immediate 'No incoming service worker found.'
rejection: a worker can still arrive via updatefound after register()
resolves, so the wait now relies on the existing timeout for the genuine
"nothing ever activates" case.

No public API changes.

Testing

  • All existing @firebase/messaging tests pass.
  • Added packages/messaging/src/helpers/registerDefaultSw.test.ts covering:
    • resolves when the registration already has an active worker;
    • resolves when a replacement worker activates after the originally observed
      worker becomes redundant (the regression, which previously timed out);
    • resolves for a worker that only appears via updatefound;
    • rejects when no worker becomes active before the timeout.

API Changes

None

@changeset-bot

changeset-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c9d81c2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@firebase/messaging Patch
firebase Patch
@firebase/messaging-compat Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chan-mai chan-mai changed the title fix(messaging): resolve getToken() when observed service worker becom… fix(messaging): resolve getToken() when observed service worker becomes redundant Aug 1, 2026
@chan-mai
chan-mai marked this pull request as ready for review August 1, 2026 18:26
@chan-mai
chan-mai requested review from a team and zwu52 as code owners August 1, 2026 18:26

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an issue where getToken() intermittently fails with a service worker registration timeout. The waitForRegistrationActive function was refactored to resolve as soon as any active worker is present, follow replacement workers via the updatefound event, and transition to watching a new worker if the currently watched worker becomes redundant. Comprehensive unit tests were also added to verify these scenarios. I have no feedback to provide as there are no review comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant