ScaleRocket/Mobile

Push Notifications

Set up Expo push notifications with permission handling, token management, and backend integration.

Push Notifications

ScaleRocket Mobile includes expo-notifications as a dependency. This guide walks you through enabling push notifications.

1. Configure the Plugin

Add the notifications plugin to app.json:

{
  "expo": {
    "plugins": [
      ["expo-notifications", {
        "icon": "./assets/notification-icon.png",
        "color": "#2563EB"
      }]
    ]
  }
}

Note: The notification icon should be a 96x96 PNG with a transparent background (Android only). iOS uses the app icon.

2. Request Permissions

You must request permission before sending notifications. Add this to your app initialization or a dedicated screen:

import * as Notifications from "expo-notifications";
import { Platform } from "react-native";

async function requestNotificationPermissions() {
  const { status: existingStatus } = await Notifications.getPermissionsAsync();
  let finalStatus = existingStatus;

  if (existingStatus !== "granted") {
    const { status } = await Notifications.requestPermissionsAsync();
    finalStatus = status;
  }

  if (finalStatus !== "granted") {
    console.log("Notification permission denied");
    return false;
  }

  // Required for Android
  if (Platform.OS === "android") {
    await Notifications.setNotificationChannelAsync("default", {
      name: "Default",
      importance: Notifications.AndroidImportance.MAX,
    });
  }

  return true;
}

3. Get the Push Token

After permissions are granted, get the Expo push token:

import Constants from "expo-constants";

async function getPushToken() {
  const token = await Notifications.getExpoPushTokenAsync({
    projectId: Constants.expoConfig?.extra?.eas?.projectId,
  });
  return token.data; // "ExponentPushToken[xxxx]"
}

4. Save the Token to Your Backend

Save the push token to your user's profile:

import { supabase } from "../lib/supabase";

async function savePushToken(token: string) {
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return;

  await supabase.auth.updateUser({
    data: { push_token: token },
  });
}

Or save it to a dedicated profiles table:

await supabase
  .from("profiles")
  .update({ push_token: token })
  .eq("id", user.id);

Save the push token using a Convex mutation:

import { useMutation } from "convex/react";
import { api } from "../convex/_generated/api";

const savePushToken = useMutation(api.users.savePushToken);
await savePushToken({ token });

5. Send a Test Notification

Use the Expo Push Notification Tool to send a test notification. Paste your ExponentPushToken[xxxx] and send.

Or use curl:

curl -H "Content-Type: application/json" \
  -d '{
    "to": "ExponentPushToken[xxxx]",
    "title": "Hello!",
    "body": "This is a test notification"
  }' \
  https://exp.host/--/api/v2/push/send

6. Handle Incoming Notifications

Configure how notifications appear when the app is in the foreground:

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: true,
  }),
});

Listen for notification taps:

import { useEffect } from "react";

useEffect(() => {
  const subscription = Notifications.addNotificationResponseReceivedListener(
    (response) => {
      const data = response.notification.request.content.data;
      // Navigate to the relevant screen based on data
    }
  );

  return () => subscription.remove();
}, []);

Important Notes

  • Push notifications require a development build (not Expo Go)
  • iOS requires a real device (simulators cannot receive push notifications)
  • The projectId must match your EAS project — run eas build:configure if not set

On this page