商店发布
提交 iOS 和 Android 发布,并在上线后运营更新。
发布阶段会把 Expo 模板的多个部分接起来:production variant、商店记录、EAS 凭证、法律 URL、隐私披露、RevenueCat 产品、Supabase webhook、版本门禁和 OTA channel 管理。
发布前检查
创建 production 商店构建前:
- 确认
APP_VARIANT=production,这样 bundle ID/package 是expo.soarstarter.com,scheme 是soar-starter-expo。 - 替换 app 名称、icon、adaptive icon、splash 和 favicon。
- 修改源图标后运行
pnpm generate:assets。 - 替换
EXPO_PUBLIC_TERMS_URL、EXPO_PUBLIC_PRIVACY_URL和EXPO_PUBLIC_EULA_URL。 - 如果设置了
EXPO_PUBLIC_LINKING_DOMAIN,部署 Universal/App Links 文件。 - 检查
app.config.ts里的 Android 权限:CAMERA、READ_MEDIA_IMAGES、POST_NOTIFICATIONS。 - 检查 iOS camera、photo library、Apple Sign-In 和 ATT 文案。
- 配置 production Supabase URL/anon key、RevenueCat SDK keys、Sentry DSN、 PostHog key 和商店 URL。
- 部署 production Supabase Edge Functions,并设置 Edge secrets。
- 确认 RevenueCat webhook 指向 production Supabase project。
- 确认
eas.jsonproduction 使用distribution: "store"、channel: "production"和autoIncrement: true。
iOS 发布
为下面的 Bundle ID 创建 iOS app 记录:
Bundle ID: expo.soarstarter.com准备:
- App 名称、副标题、分类、截图、support URL、marketing URL 和 privacy policy URL。
- Sign in with Apple capability,因为应用包含 Apple auth。
- 如果发布 RevenueCat purchases,创建 in-app purchase 产品。
- Sandbox testers 和 TestFlight tester groups。
- 如果使用 Universal Links,配置 Associated Domains。
构建并提交:
eas build --profile production --platform ios
eas submit --profile production --platform ios因为模板里的 submit.production.ios 为空,第一次 submit 会要求 Apple 凭证
或 App Store Connect API key 信息。
审核备注里说明这些流程:
- 删除账号在 Me -> Account & Security 中,通过
delete-accountEdge Function 执行。 - 法律同意由
LEGAL_VERSION版本化。 - ATT 从权限预热页请求,和法律同意分开。
- Purchases 通过 RevenueCat 和 Supabase entitlement 绑定账号。
- 除非你添加 token 持久化和发送路径,否则 push sending 没有启用。
如果测试账号有活跃 Apple subscription,删除账号前应用会提供订阅管理 URL。
Android 发布
为下面的 package name 创建 Android app:
Package name: expo.soarstarter.com准备:
- App content、target audience、content rating、截图、feature graphic、 privacy policy 和 support contact。
- Google Play App Signing 和 internal testing track。
- 如果发布 RevenueCat purchases,创建 in-app products 或 subscriptions。
- 如果使用
EXPO_PUBLIC_LINKING_DOMAIN,部署 App Links asset links。 - 通知、相机和图片/媒体权限说明。
构建并提交:
eas build --profile production --platform android
eas submit --profile production --platform android模板的 preview profile 会产出 APK,方便内部分发。production 商店包由 EAS 处理并提交到 Play。
使用和 iOS 相同的数据映射,再按 Google 的分类填写。账号数据、诊断、 analytics、购买和用户上传文件都要明确说明。
客户端可以配置 RevenueCat Android SDK,但当前 Supabase webhook 会忽略
PLAY_STORE 事件。承诺 Android purchases 解锁 Supabase entitlement 前,
需要先扩展 webhook。
隐私映射
| 服务 | 涉及数据 | 披露说明 |
|---|---|---|
| Supabase Auth | 邮箱、认证标识、profile 字段 | 注册、登录、个人资料、删除账号 |
| Supabase Database | Todos、profile、subscriptions、payments、上传元数据 | 用户拥有的数据,由 RLS 保护 |
| Supabase Storage | 上传示例文件和头像 | 文件保存在按用户隔离的路径下 |
| RevenueCat | App user ID、购买历史、产品标识 | 用于购买;entitlement source of truth 是 Supabase |
| PostHog | 配置后采集 analytics events 和设备/app 上下文 | 当前 legal consent 不会阻止 PostHog 初始化 |
| Sentry | 配置后采集 crash reports、stack traces、设备/app 上下文 | 上传 sourcemap 后 production trace 更可读 |
| Expo Notifications | 获取到的 Expo push token | 当前客户端不会持久化 token |
| ATT | 跟踪授权状态 | iOS-only,从权限预热页触发 |
上线后运营
商店页面存在后设置 URL:
EXPO_PUBLIC_APP_STORE_URL=
EXPO_PUBLIC_PLAY_STORE_URL=然后有计划地使用版本门禁:
| Key | 用途 |
|---|---|
EXPO_PUBLIC_LATEST_APP_VERSION | 软提醒用户升级 |
EXPO_PUBLIC_MIN_APP_VERSION | 强制旧版本升级 |
EXPO_PUBLIC_APP_UPDATE_URL | 门禁打开的商店或落地页 URL |
EXPO_PUBLIC_APP_UPDATE_MESSAGE | 面向用户的更新文案 |
EXPO_PUBLIC_APP_UPDATE_CONFIG_URL | 远程 JSON 覆盖 update policy |
OTA 只发布到匹配的 channel:
eas update --channel production --message "Fix production copy"保持 production、preview、development channel 分离。不要因为改动“只是 JavaScript”就把未审核的实验内容发布到 production channel。
