Announcements
Store review takes days; an announcement takes seconds: one Firestore document renders as a banner in every open surface (the kit calls these broadcasts). This is remote data, which CWS sanctions; remote code never is.
Publish a broadcast
Section titled “Publish a broadcast”Firebase console → Firestore → broadcasts collection → create a doc with
any ID. The ID doubles as the dismissal key: reuse an ID and users who
dismissed it won’t see it again.
| field | type | required | notes |
|---|---|---|---|
message |
string | yes | banner text; keep it to one line |
level |
string | no | info (default) · warning · promo; styling only |
link |
string | no | https only; renders as “Learn more” |
activeFrom |
number | no | epoch ms; hidden before this |
activeUntil |
number | no | epoch ms; hidden after this |
minVersion |
string | no | only shown on extension versions ≥ this (e.g. "1.2.0") |
Delete the doc (or set activeUntil in the past) to retract it.
Typical uses: incident notice (warning), launch or discount (promo with
an activeUntil), feature announcements. For “update available” nudges,
announce broadly and gate the feature in code; minVersion targets newer
versions, not older ranges.
How it flows
Section titled “How it flows”The background holds an onSnapshot listener on the collection (public
read-only, enforced by Firestore rules) and mirrors it into
storage.local.broadcasts; <BroadcastBanner> in the popup, sidepanel, and
options page shows the first active one. Dismissals are per-message and
local (storage.local.broadcastDismissals). Offline, the last mirrored list
keeps serving. The extension never writes to the collection; the rules say
write: if false for all clients.
Show “what’s new” after an update
Section titled “Show “what’s new” after an update”The changelog notice after an extension update rides the same banner
pipeline with no Firestore involved: runtime.onInstalled (reason
"update") writes a local broadcast to storage.local.updateNotice with
the ID update-<version> and a link to site.config.ts → urls.changelog.
<BroadcastBanner> renders it after any server broadcast. Dismissal uses
the shared per-ID store, so it’s always dismissible (a CWS policy point) and
shows once per version; the stored ID doubles as the “seen version” record.
The pure logic lives in apps/extension/utils/update-notice.ts.
