DEV Community

NISHARGA KABIR
NISHARGA KABIR

Posted on

React Native Expo Custom Push Notifications

Step 0 is for backend:

const express = require("express");
const { Expo } = require("expo-server-sdk") ;

const app = express();
const PORT = 8000;

const expo = new Expo();

app.use(express.json());

app.get("/", (req, res) => {
  res.send("Welcome to Expo Notification Backend");
});

app.post("/api/push-notification", async (req, res) => {
  const { token, title, body, metadata } = req.body;
  if (!Expo.isExpoPushToken(token)) {
    throw new Error("Invalid push token", 400);
  }

  const message = {
    to: token,
    sound: "default",
    title: title,
    body: body,
    data: metadata || {},
  };

  const tickets = await expo.sendPushNotificationsAsync([message]);

  return res.status(200).json(tickets);
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

We basically have to install this package.

"expo-server-sdk": "^3.15.0",

And using this we will send the notifications

expo.sendPushNotificationsAsync([message]);

Step 1: Generate Expo ID

eas init

We have to do this for our react-native expo project 🙂
When you generate an id you will also see it on the dashboard as well https://expo.dev/accounts/nisharga

Step 2: Create A Wrapper

Now on the app.tsx we have to create a wrapper

<PushNotificationManager>
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
</PushNotificationManager>

Now its time to create the PushNotificationManager

Step 3: 3/3 It mean you have to understand 3 things before go next :)

  1. You will get the ID once you run the mobile app project

2.and using the ID you have to hit postman route

3.It wouldn't work on the emulator. Download Expo app on your phone and try this.

Step 4: Finally full code PushNotificationManager.tsx


import React, { useEffect, PropsWithChildren } from 'react';
import { Platform } from 'react-native';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';

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

const PushNotificationManager: React.FC<PropsWithChildren<{}>> = ({
  children,
}) => {

  const registerForPushNotificationsAsync = async (): Promise<
    string | undefined
  > => {
    let token;

    if (Platform.OS === 'android') {
      await Notifications.setNotificationChannelAsync('default', {
        name: 'default',
        importance: Notifications.AndroidImportance.MAX,
        vibrationPattern: [0, 250, 250, 250],
        lightColor: '#FF231F7C',
      });
    }

    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') {
        console.warn('Failed to get push token for push notification!');
        return;
      }

      // Get Expo Push Token
      try {
        const projectId = Constants.expoConfig?.extra?.eas?.projectId;

        if (!projectId) {
          console.error('No project ID found. Please configure in app.json');
          return;
        }
        token = (
          await Notifications.getExpoPushTokenAsync({
            projectId: projectId,
          })
        ).data;
        console.log('Push Token:', token);
        return token
      } catch (error) {
        console.error('Detailed Error getting push token:', error);

        if (error instanceof Error) {
          console.error('Error name:', error.name);
          console.error('Error message:', error.message);
          console.error('Error stack:', error.stack);
        }
      }
    } else {
      console.warn('Must use physical device for Push Notifications');
    }
    return token;  
};
  useEffect(() => {
    registerForPushNotificationsAsync().then((token) => {
      if (token) { }
    });

// Notification received listener
    const receivedSubscription = Notifications.addNotificationReceivedListener(
      (notification) => {
        console.log(
          'Notification Received:',
          notification.request.content.data,
        );
      },
    );

    // Notification tap listener
    const responseSubscription =
      Notifications.addNotificationResponseReceivedListener((response) => {
        const data = response.notification.request.content.data;
        console.log('Notification Tapped:', data);
      });

    return () => {
      receivedSubscription.remove();
      responseSubscription.remove();
    };
  }, []);
  return <>{children}</>;
};

export default PushNotificationManager;`



Enter fullscreen mode Exit fullscreen mode

Top comments (0)