Skip to content
Skip to content
Goodspeed

Build apps with Push Notifications

lib/notifications.ts registers the Expo push token, creates Android channels from config, and upserts the token to a Supabase push_tokens table. Goodspeed generates Push Notifications as a standard part of every app, so the output is a working codebase from day one, not a scaffold you have to finish yourself.

WHAT GETS GENERATED

Built into every Push Notifications build

Every app Goodspeed generates with Push Notifications includes these production-ready patterns, wired together from the first build.

ItemDescriptionStrength
requestPermissionAndRegister helperRequests notification permissions, reads the Expo push token from a physical device, creates Android channels from gasConfig, and upserts to the push_tokens table in Supabase.Setup
Android notification channels from configgasConfig.features.pushNotifications.channels is an array of channel configs. lib/notifications.ts creates them at app start using setNotificationChannelAsync.Android
Global notification handlerA module-level setNotificationHandler sets shouldShowAlert, shouldPlaySound, and shouldSetBadge for all received notifications.Handler
Supabase push_tokens tableA generated migration creates a push_tokens table with user_id, token, and platform columns. The token is upserted on every app start so stale tokens rotate automatically.Backend
supabase/functions/send-push/ Edge FunctionAn Edge Function accepts a user ID and message payload, fetches the push token from push_tokens, and calls the Expo Push API to deliver the notification.Delivery

Source: gas-template repository · Engagement

REAL GENERATED CODE

A snippet from a Push Notifications app the studio shipped

This pattern comes directly from the gas-template codebase, the foundation every Goodspeed app is generated on. The studio generates Push Notifications code like this for every app in the pipeline, not just a hello-world scaffold.

  1. Token registration

    // lib/notifications.ts: register push token
    export async function requestPermissionAndRegister(
      userId: string
    ): Promise<string | null> {
      if (isWeb || !ExpoNotifications || !Device?.isDevice) return null;
      const { status } = await ExpoNotifications.requestPermissionsAsync();
      if (status !== 'granted') return null;
      const token = (await ExpoNotifications.getExpoPushTokenAsync()).data;
      await supabase.from('push_tokens')
        .upsert({ user_id: userId, token, platform: Platform.OS },
                 { onConflict: 'user_id' });
      return token;
    }
GDaily Allergens

Today's log

Gluten
Tree nuts
Shellfish
Dairy
HomeScanLogProfile

START WITH PUSH NOTIFICATIONS

Your Push Notifications app, generated