Push notifications
Your game asks the player to allow its notifications, and from then on the device is registered with Brain for the signed-in player: on iOS through Apple's push service (APNs) with your own key, on Android through Firebase Cloud Messaging. When the player opens a notification your game hears about it, with the data the notification carried.
Today Brain sends one kind of notification: a test from your studio console, to check that a device gets them. Campaigns, scheduled and targeted sends from your servers come later, and so do local notifications.
Turn push on
Add [push] to brain/game.toml:
[push]
# Android: your Firebase project's ids, from the Firebase console's project settings.
firebase_project_id = "neon-drift"
firebase_app_id = "1:123456789012:android:0a1b2c3d4e5f6a7b"
firebase_api_key = "AIzaSy..."
firebase_sender_id = "123456789012"
# Android's small notification icon: white on transparent. Without one, Android shows a bell.
android_icon = "brain/push-icon.png"
These ids are public, as Firebase's own config files are: put no keys here. iOS needs nothing in
[push]: it sends to your app's bundle id, stores.appstore.bundle_id. Devices register under a
player's Brain account, so the game needs accounts on ([accounts], or any matchmaking queue,
leaderboard, saves or products); a guest account is enough.
Your studio's keys go on the console's Secrets page, or with ase studio secret. Set them for
the studio, or for one game where it has its own:
| Secret | What it is |
|---|---|
PUSH_APNS_KEY |
Your APNs auth key, the .p8 file (App Store Connect, Users and Access, Integrations, Keys) |
PUSH_APNS_KEY_ID |
That key's id |
PUSH_APNS_TEAM_ID |
Your Apple team id |
PUSH_FCM_SERVICE_ACCOUNT |
A service account key file of your Firebase project, with the Firebase Cloud Messaging API Admin role |
ase studio secret PUSH_APNS_KEY < AuthKey_ABC123DEFG.p8
ase studio secret PUSH_FCM_SERVICE_ACCOUNT --game neon-drift < firebase-service-account.json
Your game's Push page in the console says whether iOS and Android are ready and what is still missing.
Ask for permission
The SDK never asks on its own and shows nothing before the system's prompt: ask when the player understands why, such as after they finish a match they could be told about.
func _on_notify_me_pressed() -> void:
var status := await Brain.push.request_permission()
if status == "denied":
show_hint("Notifications are off. You can turn them on in Settings.")
Brain.push.status says where the player stands:
| Status | Means |
|---|---|
undetermined |
Never asked: request_permission() shows the system's prompt |
granted |
Allowed; the device registers with Brain |
provisional |
iOS's quiet notifications, delivered without asking; registers like granted |
denied |
The player said no, or turned them off in Settings; asking again shows nothing |
unsupported |
No push here: desktop, the web and Steam, or a game without [push] |
Android 12 and older, where notifications need no permission, answer granted at once.
status_changed fires when the answer changes. Brain.push.supported() tells whether to show your
notifications option at all.
Registering devices
Once notifications are allowed, the SDK registers the device with Brain as soon as a player is signed in. It sends again only when the device's push token, its build (development or App Store) or the player changes, so a game starting sends nothing new. A device belongs to one player at a time: when another player signs in on it, it moves to them.
For a notifications toggle in your own settings:
Brain.push.unregister() # this device stops getting the player's notifications
Brain.push.register() # and gets them again
unregister() holds across restarts until register().
Opened and received notifications
func _ready() -> void:
Brain.push.opened.connect(_on_push_opened)
Brain.push.received.connect(_on_push_received)
func _on_push_opened(pushed: Dictionary) -> void:
# The player tapped it: {title, body, data}, data being the strings the sender attached.
if pushed.data.get("screen") == "shop":
open_shop()
func _on_push_received(pushed: Dictionary) -> void:
# It arrived while the game was in front, where the system shows nothing.
show_toast(pushed.title)
The notification that launched the game arrives as opened too, once Brain is ready. Each
opened notification also sends a push_opened event to your analytics, saying whether it was a
console test.
Send a test
On the console's Push page, the devices that registered most recently each have Send test.
The notification says "Test notification" and carries brain_test in its data. The page then shows
whether Apple or Google accepted it; whether it shows depends on the device's settings. Sending a
test needs a role that manages games, and each one lands in the audit log.
Every notification Apple or Google accepts counts as a push send on your studio's usage.
Exports
Android
Use Godot's Gradle build. The editor plugin adds the push plugin and Firebase's messaging library
to the export, writes your Firebase ids into the build as resources (no google-services.json) and
copies your android_icon. The export warns when an id is missing; such a build gets no token.
iOS
Turn on Entitlements > Push Notifications in your iOS export preset: Development for builds
signed for your own devices, Production for the App Store. An export of a game with [push]
reports an error while it is Disabled. ase release sets it from your provisioning profile, and refuses a profile
whose App ID lacks Push Notifications.
Development-signed builds register with Apple's sandbox, App Store and TestFlight builds with production; Brain sends each to the right one.