Push notifications
A ping from the garden
The Garden Defense Halloween event starts on Saturday. Players who open the game will see the pumpkins. But what about the ones who haven't played for a week?
A push notification is a short message sent to a device from a server. It shows on the lock screen or in the notification list, even when the game is closed. A local notification is different: the game schedules it on the device itself, like "Your sunflowers are ready", with no server involved. Both are powerful, and both are easy to abuse.
How a push travels
- 1. PermissionThe player says yes to notifications. Without that, nothing gets through.
- 2. Device tokenA long ID that works as the address of one install of the game. The game sends it to our server, which keeps it private.
- 3. Our server sendsCode on our server, like a Cloud Function, asks Firebase Cloud Messaging (FCM) to deliver a message to one token, or to everyone on a topic.
- 4. The platform deliversFCM passes it on: through Apple's push service (APNs) to iPhones, straight to Android phones, and through the browser's push service on the web.
Quick check
Kai's server wants to tell one Garden Defense player that their oak tree is fully grown. What does it need to reach that player's device?
- That install's device token, which the game sent to our server after the player said yes
- The player's phone number
- Nothing, FCM finds every player automatically
Show the answer
That install's device token, which the game sent to our server after the player said yes
The token is the address of one install of the game, and FCM uses it to route the message. No phone number is needed. Without permission and a token, there is no address to send to.
Web push for Hyper Shards
Hyper Shards is a PWA, a website players can install like an app. Web push reaches it through the service worker, the background script that also caches the game. With Firebase on the web, that script is a file called firebase-messaging-sw.js, and the site must use HTTPS.
iPhones and iPads add a rule. Since iOS 16.4, web push works only for web apps added to the Home Screen, and the permission request must come from a tap, like a button. So on iPhone, players install Hyper Shards first (Share, then Add to Home Screen).
Ask at the right moment
On Android 13 and newer, notifications are off by default for a new install until the app asks. On iPhone, the system prompt appears only the first time an app asks. If the player says no, only the Settings app can change it. One shot.
So never ask on first launch, before the player knows the game. Ask when it is clearly useful. After a player plants an oak that takes a day to grow, Garden Defense shows its own screen: "Want a ping when your tree is ready?" Only a tap on Yes opens the real system prompt.
Bolt says: Our own screen is called a pre-prompt. "Not now" there costs nothing, so we can ask again another day. Browsers notice pushy sites too: Chrome can show a quieter prompt for sites whose requests are rarely accepted.
Bug hunt
1// Hyper Shards: when to ask for notifications2window.addEventListener('load', () => {3 Notification.requestPermission();4});5 6remindBtn.addEventListener('click', async () => {7 const ok = await Notification.requestPermission();8 if (ok === 'granted') subscribe(['new_ships']);9});
remindBtn is a "Remind me about new ships" button. Which line should Kai delete?
- Line 3
- Line 7
- Line 8
Show the answer
Line 3
Line 3 asks the moment the page loads, before the player knows the game, and on iPhone a request without a tap doesn't even work. Lines 7 and 8 ask only after the player taps the button, then subscribe to the topic they chose.
Useful, not pushy
- UsefulNews the player asked for: "The pumpkin event has started. Sprig's witch hat is waiting."
- TimelySent when the news happens, at a sensible time of day for that player.
- PersonalAbout their own game: "Your oak tree is fully grown."
- Never fake urgencyNo guilt ("Sprig misses you!!"), no fake countdowns, no "last chance" for an event with two weeks left. These are dark patterns, tricks that push people against their own interest (Dark patterns: fair or manipulative?, Stage 6).
Apple's App Store rules add two more: an app must work without push, and promotional pushes need the player's clear opt-in plus a way to opt out.
Limits, quiet hours and topics
- Frequency cap: our studio rule is at most two pushes a week per game. Even good news gets annoying when it never stops.
- Quiet hours: no pushes between 21:00 and 08:00 in the player's time zone. Events start in UTC, but bedtimes don't.
- Topics: a settings screen lets players choose Events, New ships or Reminders. FCM topic messaging sends one message to every device subscribed to a topic like
events.
Android also sorts notifications into channels, and players can mute each channel separately in their phone settings.
Pick the push
The Garden Defense pumpkin event runs for three weeks. Which push should go out at 17:00 local time on day one?
- "The pumpkin event has started! Sprig's witch hat is waiting in the garden."
- "Sprig is crying because you left. Come back right now or lose everything!"
- "Last chance!!! Play in the next 3 hours or miss out forever!"
Show the answer
"The pumpkin event has started! Sprig's witch hat is waiting in the garden."
It is useful, true and sent at a sensible time. Guilt and fake urgency are dark patterns, and "last chance" is simply false on day one of a three-week event.
Measure, and keep it gentle
Watch the numbers after every send: how many players opened it, how many turned notifications off, and how many uninstalled. If opt-outs jump after a push, we sent too much or the wrong thing.
Many of our players are children, so our pushes stay gentle: nothing late at night, nothing about spending money, no pressure. A good test: would a parent reading over the player's shoulder be happy with it? Device tokens point at one person's device, so we keep them private like any player data (Keeping player data safe, Stage 4).
Bolt says: Next: updates and player feedback, where players talk back to us.
Fact-checked 9 October 2026
- WebKit: web push for web apps on iOS and iPadOS webkit.org
- Firebase Cloud Messaging firebase.google.com
- FCM: set up a JavaScript client firebase.google.com
- Android: notification runtime permission developer.android.com
- Android: notification channels developer.android.com
- App Store Review Guidelines developer.apple.com
- Chromium blog: quieter permission UI blog.chromium.org