Expo 推送通知设置
了解如何设置推送通知、获取开发和生产凭据以及发送测试推送通知。
要使用 Expo 推送通知服务,你必须通过安装一组库来配置你的应用,实现处理通知的函数,并为 Android 和 iOS 设置凭据。
🌐 To utilize Expo push notification service, you must configure your app by installing a set of libraries, implement functions to handle notifications, and set up credentials for Android and iOS.
完成本指南中列出的步骤,或观看下面更详细的视频。完成后,你将能够发送推送通知并在设备上接收它。
🌐 Complete the steps outlined in this guide or follow the more detailed video below. At the end, you'll be able to send a push notification and receive it on a device.

学习如何在 Expo 项目中设置推送通知。本视频涵盖在 Android 上为 FCM v1 配置 Firebase、在 EAS 上设置 Android 和 iOS 凭证、使用 EAS Build 构建以及使用 Expo Notifications 工具进行测试。
要让客户端准备好推送通知,需要执行以下操作:
🌐 To get the client-side ready for push notifications, the following things are required:
- 用户向其发送推送通知的权限。
- 该应用的
ExpoPushToken。
你想直接使用 FCM / APNs,而不是 Expo 推送通知服务吗?
如果你需要对通知进行更精细的控制,可能需要直接与 FCM 和 APNs 进行通信。Expo 并不会限制你使用 Expo 应用服务,并且 expo-notifications API 与推送服务无关。了解如何使用 FCM 和 APNs 发送通知。
🌐 If you need finer-grained control over your notifications, communicating directly with FCM and APNs may be necessary. Expo does not lock you into using Expo Application Services, and the expo-notifications API is push-service agnostic. Learn how to "Send notifications with FCM and APNs".
先决条件
🌐 Prerequisites
警告 重要提示: Android 模拟器和 iOS 模拟器不支持推送通知,需要使用真实设备。
本指南中描述的以下步骤使用了 EAS Build。这是设置通知的最简单方式,因为你的 EAS 项目还将包含 通知凭据。不过,你也可以在不使用 EAS Build 的情况下,通过在本地构建 你的项目 来使用 expo-notifications 库。
🌐 The following steps described in this guide use EAS Build. This is the easiest way to set up notifications since your EAS project will also contain the notification credentials. However, you can use the expo-notifications library without EAS Build by building your project locally.
1
安装库
🌐 Install libraries
运行以下命令来安装 expo-notifications、expo-device 和 expo-constants 库:
🌐 Run the following command to install the expo-notifications, expo-device and expo-constants libraries:
- npx expo install expo-notifications expo-device expo-constantsexpo-notifications库用于请求用户的权限并获取发送推送通知的ExpoPushToken。[expo-device](/versions/latest/sdk/device)用于检查应用是否在实体设备上运行。expo-constants用于从应用配置中获取projectId值。
2
添加配置插件
🌐 Add config plugin
在你的 应用配置 的 plugins 数组中添加 expo-notifications 插件:
🌐 Add the expo-notifications plugin in the plugins array of your app config:
{ "expo": { %%placeholder-start%%... %%placeholder-end%% "plugins": [ %%placeholder-start%%... %%placeholder-end%% "expo-notifications" ] } }
3
添加一个最小可运行示例
🌐 Add a minimal working example
下面的代码展示了在 React Native 应用中如何注册、发送和接收推送通知的工作示例。将其复制并粘贴到你的项目中:
🌐 The code below shows a working example of how to register for, send, and receive push notifications in a React Native app. Copy and paste it into your project:
import { useState, useEffect, useRef } from 'react'; import { Text, View, Button, 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 () => ({ shouldPlaySound: true, shouldSetBadge: true, shouldShowBanner: true, shouldShowList: true, }), }); async function sendPushNotification(expoPushToken: string) { const message = { to: expoPushToken, 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), }); } function handleRegistrationError(errorMessage: string) { alert(errorMessage); throw new Error(errorMessage); } async function registerForPushNotificationsAsync() { 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') { handleRegistrationError('Permission not granted to get push token for push notification!'); return; } const projectId = Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId; if (!projectId) { handleRegistrationError('Project ID not found'); } try { const pushTokenString = ( await Notifications.getExpoPushTokenAsync({ projectId, }) ).data; console.log(pushTokenString); return pushTokenString; } catch (e: unknown) { handleRegistrationError(`${e}`); } } else { handleRegistrationError('Must use physical device for push notifications'); } } export default function App() { const [expoPushToken, setExpoPushToken] = useState(''); const [notification, setNotification] = useState<Notifications.Notification | undefined>( undefined ); useEffect(() => { registerForPushNotificationsAsync() .then(token => setExpoPushToken(token ?? '')) .catch((error: any) => setExpoPushToken(`${error}`)); const notificationListener = Notifications.addNotificationReceivedListener(notification => { setNotification(notification); }); const responseListener = Notifications.addNotificationResponseReceivedListener(response => { console.log(response); }); return () => { notificationListener.remove(); responseListener.remove(); }; }, []); return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'space-around' }}> <Text>Your Expo push token: {expoPushToken}</Text> <View style={{ alignItems: 'center', justifyContent: 'center' }}> <Text>Title: {notification && notification.request.content.title} </Text> <Text>Body: {notification && notification.request.content.body}</Text> <Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text> </View> <Button title="按下以发送通知" onPress={async () => { await sendPushNotification(expoPushToken); }} /> </View> ); }
配置 projectId
🌐 Configure projectId
使用前面的例子,当你注册推送通知时,你需要使用 projectId。这个属性用于将 Expo 推送令牌归属到特定项目。对于使用 EAS 的项目,projectId 属性表示该项目的通用唯一标识符 (UUID)。
🌐 Using the previous example, when you are registering for push notifications, you need to use projectId. This property is used to attribute Expo push token to the specific project. For projects using EAS, the projectId property represents the Universally Unique Identifier (UUID) of that project.
projectId 会在你创建开发构建时自动设置。然而,我们建议在项目代码中手动设置它。为此,你可以使用 expo-constants 从应用配置中获取 projectId 值。
const projectId = Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId; const pushTokenString = (await Notifications.getExpoPushTokenAsync({ projectId })).data;
将 Expo 推送令牌归属到你的项目 ID 的一个优点是,当项目在不同账户之间转移或现有账户更名时,它不会改变。
🌐 One advantage of attributing the Expo push token to your project's ID is that it doesn't change when a project is transferred between different accounts or the existing account gets renamed.
4
获取开发版本的凭据
🌐 Get credentials for development builds
对于Android和iOS,设置你的凭证有不同的要求。
🌐 For Android and iOS, there are different requirements to set up your credentials.
对于 Android,你需要配置 Firebase 云消息传递 (FCM) 来获取凭据并设置你的 Expo 项目。
按照 添加 Android FCM V1 凭据 中的步骤来设置你的凭据。
警告 生成凭证需要付费的 Apple 开发者账号。
对于 iOS,确保在第一次运行 eas build 命令之前,已经在你想测试的设备上注册了你的 iOS 设备。
如果你第一次创建开发版本,系统会要求你启用推送通知。在 EAS CLI 提示时,对以下问题回答“是”:
- 为你的项目设置推送通知
- 生成新的 Apple 推送通知服务密钥
如果你未使用 EAS 构建,请手动运行
eas credentials。
6
使用推送通知工具进行测试
🌐 Test using the push notifications tool
在创建并安装开发版本后,你可以使用 Expo 推送通知工具 快速向你的设备发送测试通知。
🌐 After creating and installing the development build, you can use Expo push notifications tool to quickly send a test notification to your device.
-
启动项目的开发服务器:
Terminal-npx expo start -
在你的设备上打开开发版本。
-
生成
ExpoPushToken后,在 Expo 推送通知工具中输入该值以及其他详细信息(例如消息标题和内容)。 -
点击 发送通知 按钮。
在通过该工具发送通知后,你应该能在设备上看到通知。下面是 Android 设备接收推送通知的示例。
🌐 After sending the notification from the tool, you should see the notification on your device. Below is an example of an Android device receiving a push notification.