Switch push on
Every platform starts here, once per project.
Step 1: turn it on
On the dashboard, open your project and choose Push, then Turn on push.
Push runs beside your database, so your database restarts once, which takes a few seconds. Push is running within about a minute. Nothing else about your project changes, and turning it off later (the same page) restarts the database once more.
From a terminal it is the same (CLI 0.6.0 or later):
npx snoutdata products enable push --ref <ref>
Step 2: see what is ready
The Push tab then shows a card per platform:
| Card | Shows | What it needs from you |
|---|---|---|
| Web Push | Ready, and your project's public key | nothing: the project made its own key pair (VAPID) when push first started |
| iPhone, iPad and Mac apps (APNs) | Not set until you add a key | an APNs key from your Apple Developer account: iPhone, iPad and Mac |
| Android apps (FCM) | Not set until you add a key | a Firebase service account: Android |
From a terminal, the same reading:
npx snoutdata push credentials --ref <ref>
TRANSPORT SET
web push yes public key BKp3IHEt0nXOGNij…
apns no
fcm no
If web push says no, push is still starting; ask again in a minute.
Where your keys are kept
Your keys are rows in push.credentials, in your project's own database. Only the push server's
own role reads that table: not the service_role key, not your users, and the project's owner only
by deliberately switching to that role. SnoutData's own systems never store them, and the dashboard
passes a key straight through to your project without keeping it.
Each key is checked before it is stored: an Apple key must be a valid key that signs, and a Firebase service account must get a real token from Google. A stored key is never shown again, only what identifies it (the key id, the bundle id, the Firebase project). Uploading a new key replaces the old one, and nothing restarts.
From a server, the same is GET /push/v1/credentials (what is set, without the secrets) and
PUT /push/v1/credentials/apns or /fcm, with the service_role key. The platform pages show the
exact calls.
Step 3: a first test send
Once a platform is set up you can try it before your app's sign-in is wired up: add the device
yourself, as the project's owner, in the dashboard's SQL editor or any Postgres client
(npx snoutdata db psql --ref <ref>).
-- An iPhone app run from Xcode (its token is Apple's sandbox):
insert into push.devices (transport, token, apns_environment, app)
values ('apns', '<the device token>', 'sandbox', '<your bundle id>') returning id;
-- An Android app:
insert into push.devices (transport, token) values ('fcm', '<the registration token>') returning id;
Then send to it:
select push.send('{"title": "Hello", "body": "It works."}', device_ids => array['<that id>'::uuid]);
For a browser, let the page register itself (Browsers shows how): it prints the device's id.
How to tell it worked
A second after sending:
select m.id, m.status, d.status, d.error, d.provider_id, d.accepted_at - m.created_at as took
from push.messages m join push.deliveries d on d.message_id = m.id
order by m.id desc limit 5;
acceptedmeans Apple, Google or the browser's push service took the notification, andprovider_idis their id for it. What the screen shows after that is up to the device, so check the screen too.failedmeans it was not taken, anderroris the provider's own reason: Troubleshooting says what each one means.
In a real app, devices register themselves for the user who is signed in: Devices.