expo-server-sdk-node icon indicating copy to clipboard operation
expo-server-sdk-node copied to clipboard

Fix node sdk for deno edge functions / usage in supabase

Open benschac opened this issue 4 months ago • 0 comments

removing the require statement fixes the package for use in deno edge functions. my specific use case was for supabase edge functions.

how to test:

import 'jsr:@supabase/functions-js/edge-runtime.d.ts'
import pkg from 'expo-server-sdk'

// Try to find the Expo class in different ways
const { Expo: ExpoClass, default: ExpoDefault } = pkg as any
const Expo = ExpoClass || ExpoDefault || pkg.Expo || pkg

console.log('pkg type:', typeof pkg)
console.log('pkg keys:', Object.keys(pkg || {}))

const expo = new Expo()

Deno.serve(async (req: Request) => {
  try {
    // Hardcoded test token
    const pushToken = 'ExponentPushToken[yourtoken]'

    // Check that the push token appears to be valid
    if (!Expo.isExpoPushToken(pushToken)) {
      return new Response(JSON.stringify({ error: 'Invalid Expo push token' }), {
        status: 400,
        headers: { 'Content-Type': 'application/json' },
      })
    }

    // Create the message
    const message = {
      to: pushToken,
      sound: 'default' as const,
      title: 'Test Notification',
      body: 'This is a test notification from the patched SDK!',
      data: {
        withSome: 'data',
        timestamp: new Date().toISOString(),
      },
    }

    // Send the notification
    const chunks = expo.chunkPushNotifications([message])
    const tickets = []

    for (const chunk of chunks) {
      try {
        const ticketChunk = await expo.sendPushNotificationsAsync(chunk)
        console.log('Ticket chunk:', ticketChunk)
        tickets.push(...ticketChunk)
      } catch (error) {
        console.error('Error sending chunk:', error)
        throw error
      }
    }

    return new Response(
      JSON.stringify({
        success: true,
        message: 'Push notification sent!',
        tickets,
        token: pushToken,
      }),
      {
        headers: { 'Content-Type': 'application/json' },
        status: 200,
      }
    )
  } catch (error) {
    console.error('Error in test-expo-push function:', error)
    return new Response(
      JSON.stringify({
        error: error.message || 'Failed to send push notification',
        details: error,
      }),
      {
        headers: { 'Content-Type': 'application/json' },
        status: 500,
      }
    )
  }
})

/* To invoke locally:

  1. Run `supabase start` (see: https://supabase.com/docs/reference/cli/supabase-start)
  2. Make an HTTP request:

  curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/test-expo-push' \
    --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \
    --header 'Content-Type: application/json' \
    --data '{}'

*/

patched version shipped to npm from my fork:

{
  "imports": {
    "@supabase/supabase-js": "https://esm.sh/@supabase/[email protected]",
    "expo-server-sdk": "npm:@benschac/[email protected]"
  }
}

run npx supabase functions serve test-expo-push --no-verify-jwt

and curl -X POST http://127.0.0.1:54321/functions/v1/test-expo-push

you should get a push notif to your device.

benschac avatar Aug 18 '25 02:08 benschac