从Reactjs Dashboard向Android和iOS设备发送Expo推送通知

dgsult0t  于 2022-12-03  发布在  React
关注(0)|答案(1)|浏览(150)

我有一个安装在Android和iOS设备上的Expo应用程序。这些应用程序使用Firebase作为后端。我还在Reactjs中创建了一个 Jmeter 板,也使用相同的Firebase作为后端。
我想在Reactjs Dashboard上执行某些事件时向特定用户发送通知。例如:我将order_status从“pending”更改为“delivered”,然后firebase事件更改firebase集合中该用户的order_status,因此我希望用户知道其订单已被分派。
如何在Android和iOS上实现这一点?
如何在Android和iOS上实现这一点?

解决方案:
用于设置接收通知的应用端代码:

const [expoPushToken, setExpoPushToken] = useState('');
  const [notification, setNotification] = useState(false);
  const notificationListener = useRef();
  const responseListener = useRef();


 async function sendPushNotification(expoPushToken) {
    const message = {
      to: expoPushToken,
      sound: 'default',
      title: 'Original Title',
      body: 'And here is the body!',
      data: { someData: 'goes here' },
    };

    console.log(expoPushToken);

    await fetch('https://exp.host/--/api/v2/push/send', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Accept-encoding': 'gzip, deflate',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(message),
    });
  }

  async function registerForPushNotificationsAsync() {
    let token;
    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') {
        alert('Failed to get push token for push notification!');
        return;
      }
      token = (await Notifications.getExpoPushTokenAsync()).data;
      console.log(token);
    } else {
      alert('Must use physical device for Push Notifications');
    }

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

    return token;
  }


useEffect(() => {
    registerForPushNotificationsAsync().then(token => setExpoPushToken(token));

    // This listener is fired whenever a notification is received while the app is foregrounded
    notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
      setNotification(notification);
    });

    // This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
    responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
      console.log(response);
    });

    return () => {
      Notifications.removeNotificationSubscription(notificationListener.current);
      Notifications.removeNotificationSubscription(responseListener.current);
    };
  }, []);

//在导出App函数外编写以下代码

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: false,
  }),
});
  • 您可能需要使用以下方式安装Expo-notification:
    npx expo安装expo通知

从上面的代码中,你可以得到push令牌,首先你可以手动使用它来测试通知,然后你最终可以将所有用户的设备push令牌存储在某个firebase DB或自定义DB中。

服务器端代码:

  • 请先安装此库npm i node-fetch
  • 推送令牌如下所示:指数推送令牌[KA2CcEFollWMq_9TmIddctr]
import fetch from "node-fetch";

  async function sendPushNotification(expoPushToken) {
      const android = "pushToken";
      const ios = "pushToken";
      const message = {
          to: ios,
          sound: 'default',
          title: 'Original Title',
          body: 'And here is the body!',
          data: { someData: 'goes here' },
      };


   await fetch('https://exp.host/--/api/v2/push/send', {
          method: 'POST',
          headers: {
              Accept: 'application/json',
              'Accept-encoding': 'gzip, deflate',
              'Content-Type': 'application/json',
          },
          body: JSON.stringify(message),
      });
  }

在结束时调用该函数sendPushNotification();

brgchamk

brgchamk1#

下面是expo nodejs sdk的代码,检查other languages/frameworks
这更像是伪代码

import Expo from 'expo-server-sdk';

// let sentNotificationId = //id for entry in db

   //  generating custom objects to store them in DB
   const pushNotificationsItems = [{
            // info like userId
            // sentNotificationId, entry id etc
            // data mostly needed by the app
            to: notification.token,
            notificationBody: {
              // expo push notification related info
              to: notification.token, // expo token
              title: `Some title`,
              body: message,
              data: {
               //custom data to be used in app
              }
            }
          }
   ]

 // make db entries with data you need

// checking valid expo messages
      let tickets = [];

      let notificationMessages = [];

      for (const notification of pushNotificationsItems) {

        if (!Expo.isExpoPushToken(notification.to)) {
          continue
        }

        notificationMessages.push(notification.notificationBody)

      }

// send actual notification using expo client

      const expo = new Expo({});

      const chunks = expo.chunkPushNotifications(notificationMessages);

      //console.log('message chunks', chunks)

      const resolvedPromises = await Promise.allSettled(map(chunks, async chunk => {

        const ticketChunks = await expo.sendPushNotificationsAsync(chunk);

        tickets.push(...ticketChunks)

      }));

// saving the response if needed
      if (tickets.length) {
        const mappedTickets = map(tickets, t => {

          return {
            data: t,
            notificationSentId: sentNotificationId,
            organisationId,
            createdAt: getCurrentUTCISOString() || '',
          }

        })

        await this.prisma.notificationResponse.createMany({
          data: [...mappedTickets]
        })
      }

希望能对你有所帮助

相关问题