推送通知
在EasyStarter App端完成推送功能配置
推送通知
EasyStarter 默认关闭 App 通知。原因是 iOS 和 Android 都需要先配置各自的推送凭证,未配置时直接开启会导致真机打包或签名失败。
通知功能最好使用真机测试。模拟器很容易收不到推送通知,即使配置正确,也可能无法正常完成测试。
1. 开启通知
打开 packages/app-config/src/app-config.ts,找到 notifications,把 enabled 改为 true:
notifications: {
enabled: true,
provider: "expo",
},保存后,从项目根目录执行:
pnpm -F native prebuild这个命令会在现有 iOS 和 Android 工程中同步最新配置,并把通知所需的原生配置写进去。
2. 配置 iOS APNs(iOS App 需要设置这个)
推荐同时参考 Expo 官方文档:
在 Apple Developer 开启推送
- 打开 Apple Developer Identifiers
- 找到与你的
ios.bundleIdentifier一致的 App ID - 进入 App ID
- 勾选 Push Notifications
- 点击 Save
模板默认 Bundle ID 是 native.easystarter.dev。如果你已经改成自己的 Bundle ID,请选择自己的 App ID。
配置 APNs Key
先在 Apple Developer 创建 APNs Key:
- 打开 Apple Developer Keys
- 点击 + 创建新的 Key
- 填写 Key 名称,并勾选 Apple Push Notifications service (APNs)
- 点击 Continue → Register
- 下载
.p8文件,并保存页面显示的 Key ID - 获取 Apple Team ID:登录 Apple Developer Account,打开 Membership details,复制页面中的 Team ID(由 Apple 分配的 10 位字符串)
.p8 文件只能在 Apple Developer 创建时下载一次,请妥善保存,不要提交到 Git。
方法一:使用 EAS CLI
进入 Native 目录并运行:
cd apps/native
pnpm dlx eas-cli credentials运行后按下面操作:
- 选择 iOS
- 选择要使用的构建环境,例如 development
- 如果提示登录 Apple Developer,请登录并选择正确的 Team
- 选择 Push Notifications: Manage your Apple Push Notifications Key
- 选择 Set up your project to use Push Notifications
- 如果提示使用已有的 Push Key,请选择 [Add a new push key]
- 当出现 Generate a new Apple Push Notifications service key? 时选择 No
- 在 Path to P8 file 中填写刚才下载的
.p8文件路径 - 填写凭证信息:
- Key ID:创建 APNs Key 成功后,复制 Apple Developer 页面显示的 Key ID。如果已经关闭该页面,可以重新打开 Apple Developer Keys,选择刚才创建的 Key 后查看
- Apple Team ID:前往 Apple Developer Account 获取
完成后,EAS CLI 会将这个 Push Key 配置到当前项目。
方法二:通过 Expo 网页配置
- 登录 Expo Dashboard
- 进入 Credentials → Android & iOS credentials → Apple Push Keys
- 上传
.p8文件
完成配置后重新构建 iOS App
无论使用方法一还是方法二,配置完成后都需要重新构建 App。将 iPhone 连接到电脑并在手机上选择信任此电脑,然后在项目根目录运行:
pnpm -F native dev:ios-device按照提示选择你的 iPhone。命令执行完成后,新构建的 App 会自动安装到手机上。
iOS Provisioning Profile 缺少推送权限
如果构建时提示 Provisioning Profile 缺少 Push Notifications 或 aps-environment,按下面操作:
- 找到
apps/native/ios/EasyStarterNative.xcworkspace,使用 Xcode 打开该文件 - 在 Xcode 选择 EasyStarterNative Target
- 打开 Signing & Capabilities
- 开启 Automatically manage signing
- 确认 Team 正确。模板默认 Team 是
8622M955TV,使用自己的 Apple 账号时请改成自己的 Team
完成后,等待 Xcode 自动刷新 Provisioning Profile。
3. 配置 Android FCM V1(安卓 App 需要设置这个)
完整操作请参考 Expo 官方文档:FCM V1 Credentials。
创建 Firebase Android App
-
创建或选择一个 Firebase 项目
-
添加 Android App
-
Package Name 填写
apps/native/app.config.ts中的android.package -
下载
google-services.json -
将文件放到:
apps/native/google-services.json -
在
apps/native/app.config.ts的android配置中添加:apps/native/app.config.ts android: { googleServicesFile: "./google-services.json", },
创建 FCM V1 凭证
-
在 Firebase 打开 Project settings → Service accounts
-
点击 Generate new private key
-
下载 Service Account JSON 文件
-
进入
apps/native并运行:pnpm dlx eas-cli credentials -
依次选择:
- Android
- production
- Google Service Account
- Manage your Google Service Account Key for Push Notifications (FCM V1)
- Upload a new service account key
-
上传刚才下载的 Service Account JSON
Service Account JSON 包含私钥,不要提交到 Git。
重新生成并构建 Android App
回到项目根目录执行:
pnpm -F native prebuild
pnpm -F native dev:android-device安装新构建的 App 后再测试通知。
4. 配置 Expo Access Token
EasyStarter 发送通知时需要 Expo Access Token。
-
进入 Credentials → Access tokens → Personal access tokens
-
点击 Create token
-
填写 Token Name,例如
easystarter-push-production,创建后复制 Access Token -
写入本地 Server 环境变量:
apps/server/.dev.vars EXPO_ACCESS_TOKEN=your-expo-access-token -
写入生产 Server 环境变量:
apps/server/.env.production EXPO_ACCESS_TOKEN=your-expo-access-token -
部署生产环境前上传 Secret:
pnpm -F server secrets:bulk:production
不要把 Access Token 写到 EXPO_PUBLIC_* 变量或 App 代码中。
如果还没有执行最新数据库迁移,运行:
pnpm db:migrate:local
pnpm db:migrate5. 在 App 中测试通知
真机无法通过 localhost 访问电脑上的 Server,因此真机测试必须使用 ngrok。如果已经配置并正在运行 ngrok,可以跳过下面的 ngrok 配置步骤。
先启动 ngrok:
ngrok http 3001复制 ngrok 显示的 HTTPS 地址,例如 https://abc123.ngrok-free.app,并修改以下两个文件:
SERVER_URL=https://abc123.ngrok-free.appEXPO_PUBLIC_SERVER_API_URL=https://abc123.ngrok-free.app两个地址必须保持一致。免费 ngrok 地址发生变化后,也需要同时更新这两个文件。
保持 ngrok 运行,然后在项目根目录启动 Server:
pnpm -F server dev再打开一个终端,在项目根目录运行 iOS 真机 App:
pnpm -F native dev:ios-device或运行 Android 真机 App:
pnpm -F native dev:android-device然后在 App 中:
- 登录账号
- 打开 设置 → 通知
- 点击 开启系统通知
- 允许系统通知权限
- 点击 发送测试通知
测试按钮只会向当前安装的 App 发送一条测试消息。
App 在前台时会显示 App 内提示;要测试系统通知栏,请先把 App 切到后台再发送。
请使用重新构建的 Development Build 或 Release Build 测试,不要使用 Expo Go。
6. 使用 Expo 网站测试
也可以打开 Expo Push Notifications Tool 发送测试通知。
Recipent
填写当前设备的 Expo Push Token,格式类似:
ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]获取方式:
- 先在 App 中登录并允许通知
- 本地环境运行
pnpm db:studio:local,生产环境运行pnpm db:studio - 打开
notification_subscription表 - 找到
provider为expo的当前设备记录 - 复制
provider_subscription_id
Access Token
填写前面创建的 Expo Access Token,也就是 EXPO_ACCESS_TOKEN 的值。
Data (JSON string)
可以填写:
{"kind":"self_test","destination":{"type":"notification_settings"}}点击通知后会打开 App 的通知设置页。
如果只想测试通知是否能显示,也可以留空。填写时必须使用合法 JSON,字段和文本都要使用双引号。
其他常用字段:
| 字段 | 填写内容 |
|---|---|
| Message title | 测试通知标题 |
| Message body | 测试通知内容 |
| Channel ID | Android 填 default |
| Sound name | 填 default |
使用其他推送服务商
EasyStarter 的通知发送层基于 NotificationProvider 接口设计,可以扩展 OneSignal、Braze、Customer.io、CleverTap 等其他推送服务商。下面以 OneSignal 为例。
第一步:扩展服务商类型
打开 packages/app-config/src/types.ts,将新服务商追加到 SUPPORTED_NOTIFICATION_PROVIDERS:
export const SUPPORTED_NOTIFICATION_PROVIDERS = ["expo", "onesignal"] as const;第二步:接入 App 端 SDK
按照服务商提供的 Expo 或 React Native 文档安装 SDK 和 Expo Plugin,并完成 iOS APNs、Android FCM 配置。
然后修改 apps/native/hooks/use-notification-subscription-sync.ts,将 Expo Push Token 替换为新服务商返回的设备推送标识,并将其注册到 Server。
不同服务商的设备推送标识不能混用。切换服务商后,用户需要打开新版本 App,让设备重新注册。
第三步:实现 Provider
在 apps/server/src/notifications/providers/ 下新建服务商文件,并实现 NotificationProvider 接口:
apps/server/src/notifications/providers/onesignal.tsProvider 需要负责:
- 使用服务商 API 批量发送通知
- 将发送结果转换为成功或失败状态
- 查询并返回通知送达结果
- 设置服务商允许的单次发送和查询数量
可以参考现有的 apps/server/src/notifications/providers/expo.ts。
第四步:注册服务商
打开 apps/server/src/notifications/provider.ts,导入新 Provider,并在 switch 中添加对应分支:
import { createOneSignalNotificationProvider } from "./providers/onesignal";
// Add this branch to the existing switch.
case "onesignal":
return createOneSignalNotificationProvider({
appId: env.ONESIGNAL_APP_ID,
apiKey: env.ONESIGNAL_API_KEY,
});同时将服务商需要的密钥写入 Server 环境变量。
第五步:切换配置
打开 packages/app-config/src/app-config.ts,将 notifications.provider 改为新服务商:
notifications: {
enabled: true,
provider: "onesignal",
},然后在项目根目录执行:
pnpm -F native prebuild
pnpm -F native dev:ios-deviceAndroid 真机使用:
pnpm -F native dev:android-device接入前可以先参考 Expo 的 Push Notification Services Guide 和对应服务商的官方接入文档。