Skip to content

Instantly share code, notes, and snippets.

@javierguzman
Created February 26, 2023 08:58
Show Gist options
  • Save javierguzman/9249d2b88f56793dafcb8cd182ff843b to your computer and use it in GitHub Desktop.
Save javierguzman/9249d2b88f56793dafcb8cd182ff843b to your computer and use it in GitHub Desktop.
RN notifications with supabase
// 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/std@0.131.0/http/server.ts';
import { default as axiod } from 'https://deno.land/x/axiod@0.26.2/mod.ts';
import * as djwt from 'https://deno.land/x/djwt@v2.2/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;
}
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