On this page

Push notifications

Send push notifications to iOS, Android and web browsers from SQL, Edge Functions or your server, with an in-app inbox per user.

Push notifications deliver messages to your users' devices: iPhones and iPads through Apple (APNs), Android through Firebase Cloud Messaging, and browsers through Web Push. Every message can also go into the user's in-app inbox, a table in your database that your app reads and that updates live. Sending runs on your project's own server; there is no extra charge within your plan's monthly allowance.

#Limits

LimitFreeProScaleEnterprise
Push notifications per month (per project)10,0001,000,0005,000,00025,000,000

Each device a message reaches counts once. When the month's allowance is used up, further messages are marked failed with the reason; the inbox still gets them.

#Set it up

  1. Open Studio › Integrations › Push and click Turn on. Web Push works straight away: StitchDB creates your project's Web Push key pair.
  2. iOS: in your Apple developer account, go to Certificates, Identifiers & Profiles › Keys and create a key with Apple Push Notifications service (APNs). Upload the .p8 file in Studio with its Key ID, your Team ID and your app's bundle ID. Turn off Production for builds run from Xcode (sandbox).
  3. Android: in the Firebase console, open Project settings › Service accounts › Generate new private key and upload the JSON file in Studio.

The key files are stored encrypted and only used on your project's server. Send a test in Studio sends a notification to one user.

#Register devices

Register the device after the user signs in, and again whenever the push token changes. A device belongs to the signed-in user; register it again after a different user signs in.

// The APNs device token (hex) or the FCM registration token from your app
await stitchdb.push.register({ platform: 'ios', token: apnsToken })
await stitchdb.push.register({ platform: 'android', token: fcmToken, topics: ['news'] })

// On sign-out
await stitchdb.push.unregister({ platform: 'ios', token: apnsToken })

Topics group devices, for example everyone who follows a team: stitchdb.push.subscribe('team-42') adds the user's devices, unsubscribe removes them. Tokens that Apple, Google or the browser report as no longer valid are turned off automatically.

#Send

Sending needs the service_role key, so it happens on your server, in an Edge Function or in SQL. Messages are queued and delivered within a second or two; temporary errors are retried.

-- One user (also stored in the inbox)
select push.notify('<user-id>', 'Order shipped', 'Your order #1042 is on its way', '{"order": 1042}');

-- Several users, or everyone subscribed to a topic
select push.notify_many(array['<user-id>', '<user-id>']::uuid[], 'New comment', 'Someone replied to you');
select push.notify_topic('news', 'Big news', 'Version 2 is out');

-- From a trigger
create function notify_shipped() returns trigger language plpgsql security definer set search_path = '' as $
begin
  perform push.notify(new.user_id, 'Order shipped', 'Order #' || new.id || ' is on its way', jsonb_build_object('order', new.id));
  return new;
end $;
create trigger order_shipped after update of status on public.orders
  for each row when (new.status = 'shipped') execute function notify_shipped();

The SQL functions can only be called by the service_role and by your own functions; anon and authenticated cannot send.

#In-app inbox

Messages to users (not topics) are stored in push.notifications unless you pass inbox: false. Each user can only read and mark their own notifications, and new ones arrive live through Realtime:

JavaScript
const { notifications, unread } = await stitchdb.push.inbox({ limit: 20 })
await stitchdb.push.markRead([notifications[0].id])   // or 'all'
await stitchdb.push.deleteNotifications([notifications[0].id])

const stop = await stitchdb.push.onNotification((n) => showBadge(n))

#Tables

TableWhat it holds
push.devicesRegistered devices: user, platform, token or browser subscription, topics, when it was last used or turned off
push.messagesEvery message sent: target, title, status (queued, sending, sent, partial, failed), counts and error
push.deliveriesOne row per device per message, with the push service's answer
push.notificationsThe in-app inbox (readable by its user)
push.usageDevices reached per month, counted against the plan limit

Messages and deliveries are kept for 30 days. Studio shows the registered devices per platform, the month's usage and the last 20 messages. Turn off stops sending and refuses new devices; the push schema stays until you drop it.