Created
February 26, 2023 08:58
-
-
Save javierguzman/9249d2b88f56793dafcb8cd182ff843b to your computer and use it in GitHub Desktop.
RN notifications with supabase
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Follow this setup guide to integrate the Deno language server with your editor: | |
// https://deno.land/manual/getting_started/setup_your_environment | |
// This enables autocomplete, go to definition, etc. | |
import { serve } from 'https://deno.land/[email protected]/http/server.ts'; | |
import { default as axiod } from 'https://deno.land/x/[email protected]/mod.ts'; | |
import * as djwt from 'https://deno.land/x/[email protected]/mod.ts'; | |
import * as types from './types'; | |
serve(async (req) => { | |
const { name } = await req.json(); | |
const data = { | |
message: `Hello ${name}!` | |
}; | |
return new Response(JSON.stringify(data), { | |
headers: { 'Content-Type': 'application/json' } | |
}); | |
}); | |
export async function sendFirebaseMessageToDevice( | |
deviceToken: string, | |
payload: types.MessagingPayload | |
) { | |
const url = | |
'https://fcm.googleapis.com/v1/projects/:project/messages:send'.replace( | |
':project', | |
Deno.env.get('FIREBASE_PROJECT_ID') | |
); | |
const authToken = await getGoogleAccessToken(); | |
return axiod.post( | |
url, | |
{ | |
message: { | |
...payload, | |
token: deviceToken | |
} | |
}, | |
{ | |
headers: { | |
'Content-Type': 'application/json', | |
Authorization: `Bearer ${authToken}` | |
} | |
} | |
); | |
} | |
async function getGoogleAccessToken() { | |
const now = new Date(); | |
const expireDate = new Date(now.getTime() + 60 * 60 * 1000); | |
const expireDateInSec = expireDate.getTime() / 1000; | |
const iatInSec = now.getTime() / 1000; | |
const jwt = await djwt.create( | |
{ alg: 'RS256', typ: 'JWT' }, | |
{ | |
iss: Deno.env.get('FIREBASE_CLIENT_EMAIL'), | |
scope: 'https://www.googleapis.com/auth/firebase.messaging', | |
aud: 'https://oauth2.googleapis.com/token', | |
exp: expireDateInSec, | |
iat: iatInSec | |
}, | |
Deno.env.get('FIREBASE_PRIVATE_KEY') | |
); | |
const token = await getOAuthToken(jwt); | |
return token.access_token; | |
} | |
async function getOAuthToken(jwt: string) { | |
const response = await axiod.post<{ | |
access_token: string; | |
expires_in: number; | |
token_type: string; | |
}>( | |
'https://oauth2.googleapis.com/token', | |
`grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=${jwt}`, | |
{ | |
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } | |
} | |
); | |
return response.data; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState, useRef } from 'react'; | |
import * as Notifications from 'expo-notifications'; | |
import { Subscription } from 'expo-modules-core'; | |
import * as Device from 'expo-device'; | |
import { Platform } from 'react-native'; | |
Notifications.setNotificationHandler({ | |
handleNotification: async () => ({ | |
shouldShowAlert: true, | |
shouldPlaySound: false, | |
shouldSetBadge: true | |
}) | |
}); | |
const useNotifications = () => { | |
const [isGranted, setIsGranted] = useState(false); | |
const [pushToken, setPushToken] = useState(''); | |
const notificationListener = useRef<Subscription>(); | |
const responseListener = useRef<Subscription>(); | |
async function registerForNotifications() { | |
let token: Notifications.ExpoPushToken; | |
if (Device.isDevice) { | |
const { status: existingStatus } = | |
await Notifications.getPermissionsAsync(); | |
let finalStatus = existingStatus; | |
if (existingStatus !== 'granted') { | |
const { status } = await Notifications.requestPermissionsAsync(); | |
finalStatus = status; | |
} | |
if (finalStatus !== 'granted') { | |
setIsGranted(false); | |
return; | |
} | |
setIsGranted(true); | |
await registerNotificationChannel(); | |
token = await Notifications.getExpoPushTokenAsync(); | |
setPushToken(token.data); | |
} | |
} | |
async function registerNotificationChannel() { | |
if (Platform.OS === 'android') { | |
await Notifications.setNotificationChannelAsync('default', { | |
name: 'default', | |
importance: Notifications.AndroidImportance.MAX, | |
vibrationPattern: [0, 250, 250, 250], | |
lightColor: '#FF231F7C' | |
}); | |
} | |
} | |
useEffect(() => { | |
registerForNotifications(); | |
}, []); | |
useEffect(() => { | |
if (isGranted) { | |
notificationListener.current = | |
Notifications.addNotificationReceivedListener((notification) => { | |
// this is called when a notification arrives | |
// setNotification(notification); | |
console.log('notification arrived'); | |
}); | |
responseListener.current = | |
Notifications.addNotificationResponseReceivedListener((response) => { | |
// this is called when the user taps the notification | |
console.log('User pressing notification'); | |
console.log(response); | |
}); | |
return () => { | |
Notifications.removeNotificationSubscription( | |
notificationListener.current | |
); | |
Notifications.removeNotificationSubscription(responseListener.current); | |
}; | |
} | |
}, [isGranted]); | |
return { areNotificationsEnabled: isGranted, pushToken }; | |
}; | |
export default useNotifications; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment