使用Expo开发App解决消息推送问题(iOS,Android)

3,018 阅读4分钟

在上篇文章中,我们基于expo搭建了App的基础框架。在现代移动应用中,消息推送功能是提升用户体验的重要组成部分。本文将指导你如何在Expo环境中实现消息推送的功能,包含iOS与Android,以帮助你的用户及时接收到重要信息。

什么是Expo?

Expo是一个开源平台,可帮助开发者轻松构建和部署React Native应用。它提供了许多工具和服务,简化了应用开发流程,尤其是在处理消息推送方面。

准备工作

在开始之前,确保你已经完成如下准备工作:

  1. 安装Node.js:Expo需要Node.js环境来工作。

  2. 安装Expo CLI:在终端中运行以下命令安装Expo CLI:

    npm install -g expo-cli
    
  3. 安装Java SDK11版本:因为后续实现Android的消息推送需要Java SDK的11版本,所以这里必须安装Java 11。

  4. 创建新项目

    expo init MyAwesomeApp
    cd MyAwesomeApp
    

设置消息推送- iOS

这里默认您已经有了iOS的开发者账号,并且在appstoreconnect.apple.com/apps/ 已经注册过项目。iOS的消息推送比较简单,可以直接使用Expo自带的消息推送库。

1. 安装所需依赖

使用以下命令安装expo-notifications库,它支持推送通知的功能:

expo install expo-notifications

2. 配置应用

接下来,打开你的app.json文件,添加推送通知的配置:

{
  "expo": {
    "notification": {
      "icon": "./assets/icon.png",
      "color": "#000000"
    }
  }
}

3. 请求权限

在你的组件中,请求用户的通知权限:

import React, { useEffect } from 'react';
import { Button, Platform } from 'react-native';
import * as Notifications from 'expo-notifications';
import * as Permissions from 'expo-permissions';

const App = () => {
  useEffect(() => {
    registerForPushNotificationsAsync();
  }, []);

  const registerForPushNotificationsAsync = async () => {
    const { status: existingStatus } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
    let finalStatus = existingStatus;

    if (existingStatus !== 'granted') {
      const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
      finalStatus = status;
    }

    if (finalStatus !== 'granted') {
      alert('通知权限未获得!');
      return;
    }

    const token = (await Notifications.getExpoPushTokenAsync()).data;
    console.log(token); // 将token发送到服务器
  };

  return (
    <Button title="发送推送" onPress={sendPushNotification} />
  );
};

const sendPushNotification = async () => {
  const message = {
    to: '<YOUR_EXPO_PUSH_TOKEN>',
    sound: 'default',
    title: '通知标题',
    body: '这是消息的内容。',
    data: { someData: 'goes here' },
  };

  await Notifications.scheduleNotificationAsync({
    content: message,
    trigger: null,
  });
};

export default App;

4. 发送推送通知

在上面的代码中,sendPushNotification函数使用Expo的推送通知服务发送消息。替换<YOUR_EXPO_PUSH_TOKEN>为接收通知的用户的设备Token。

5. 在服务器上处理推送请求

为了更好地管理推送通知,你可能想在服务器上处理发送请求。可以使用Node.js和axios库来实现:

const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');

const app = express();
app.use(bodyParser.json());

app.post('/send-notification', async (req, res) => {
  const { token, message } = req.body;

  try {
    await axios.post('https://exp.host/--/api/v2/push/send', {
      to: token,
      sound: 'default',
      title: message.title,
      body: message.body,
    });
    res.status(200).send('通知已发送');
  } catch (error) {
    console.error(error);
    res.status(500).send('发送通知失败');
  }
});

app.listen(3000, () => {
  console.log('服务器正在运行在 http://localhost:3000');
});

设置消息推送- Android

Expo的Android端的消息推送需要使用Google的一些服务,因为国内的网络原因,无法使用。这里我们使用国内的一款优秀的消息推送工具个推来实现Android端消息推送。

  1. 安装个推:在终端中运行以下命令安装个推:

    npm install react-native-getui
    
  2. 注册账号:去个推官网注册账号www.getui.com 并创建应用,获取到应用的AppID、AppKey及 AppSecret。

  3. 使用方法

import Getui from 'react-native-getui';
function App(props) {
   useEffect(() => {
    if (Platform.OS !== 'ios') {
      // 以下传递事件
      const receiveRemoteNotificationSub = NativeAppEventEmitter.addListener(
        'receiveRemoteNotification',
        (notification) => {
          handleNotification(notification);
        }
      );

      const clickRemoteNotificationSub = NativeAppEventEmitter.addListener(
        'clickRemoteNotification',
        (notification) => {
          handleNotification(notification);
        }
      );
      Getui.clientId((param) => {
        addUserExpoToken(param)
        setClientId(param);
        console.log("clientId---", param)
      });
      Getui.version((param) => {
        setVersion(param);
        console.log('version---:', param)
      });

      Getui.status((param) => {
        let status = '';
        switch (param) {
          case '0':
            status = '正在启动';
            break;
          case '1':
            status = '启动';
            break;
          case '2':
            status = '停止';
            break;
        }
        setStatus(status);
      });
    }
  }, []);

}

因为react-native-getui不支持Expo,所以这里我们要采用裸工作流的方式打包Android端App,以下是打包步骤及中间需要修改的地方:

  1. 在终端中运行以下命令:
npx expo prebuild

运行完成后,文件夹根目录下会生成两个文件夹分别是androidios,这里我们只关注android这个文件夹。

  1. 打开android/app/build.gradle文件在defaultConfig下添加以下代码。拿到上述的AppID、AppKey及 AppSecret。
        // 配置个推的三个参数
        manifestPlaceholders = [
            GETUI_APPID : "AppID",
            GETUI_APP_ID : "AppID",
            GETUI_APP_KEY : "AppKey",
            GETUI_APP_SECRET : "AppSecret"
        ]
  1. 注释react-native-getui中影响打包的代码,每次安装新的插件后都要在node_modules文件夹中找到 react-native-getui/android/build.gradle文件注释以下代码

image.png

image.png

image.png

Android端打包命令

cd android
./gradlew assembleRelease

运行完以上命令,执行完成后在/android/app/build/outputs/apk/release中会生成app-release.apk

请注意:这种方式无法在开发环境测试消息推送,可使用模拟器安装打包后的apk文件进行调试。

小结

通过以上步骤,你已经成功设置了在Expo应用中使用消息推送的基本功能。可以根据自身业务需求调整推送通知的内容和触发条件。例如,根据特定事件(如用户登录、订单状态更新等)发送通知,增强用户体验!

希望这篇文章能帮助你更好地使用Expo进行App开发。若有任何疑问,可以在评论区交流。