OneSignal 给免费版设置了硬性上限。移动推送和应用内消息即将在超过 1000 月活用户(MAU)后不再免费。新账户从 2026 年 9 月 1 日起受限,存量账户从 10 月 1 日起受限。如果您的 App 月活用户超过一千,现在有 3 个选择:留下并付费、缩减触达规模,或迁移到其他平台。
变化内容与时间点
- 免费版在 1000 MAU 以下继续可用。超过这个数字,移动推送和应用内消息将进入付费阶梯。
- 生效时间: 根据 OneSignal 的计费 FAQ,新账户限额自 2026 年 9 月 1 日生效,存量账户自 10 月 1 日生效。
- 门槛: 移动推送和应用内消息低于 1000 MAU 不受影响。一旦超出,这两个渠道会停止发送,直到升级付费方案。
- 不受影响的渠道: Web 推送、邮件和短信继续按原有方案额度运行不变。此次调整只针对移动端。
- Journey(用户旅程)同样受影响: 任何发送推送或应用内消息的旅程步骤都会跳过移动端订阅用户。
- 删除订阅用户不是解决办法。 如果您删除的移动端订阅用户在过去 30 天内曾活跃过,账户只有在删除后满 30 天、且这期间始终没有超过限额的情况下,才能重新恢复免费额度。
迁移是怎么运作的
如果您决定迁移,有一点会改变您的规划方式:迁移由我们来完成。您这边需要准备的只有三项:一份导出文件、您的推送凭证,以及在下一个 App 版本中替换 SDK。其余的工作(清洗数据、映射平台、重建标签、导入用户、验证送达率)都由我们负责。
切换分两条轨道同时进行。一次性导入会迁移您现有的用户基础,这样在任何用户更新 App 之前,您的受众从第一天起就可以被触达。之后,SDK 会在用户安装新版本时接管每一台设备。这两个环节都需要,而且互不阻塞。
1. 哪些内容可以迁移,哪些不能
您不需要自己盘点这些内容。以下是完整情况,让您在迁移过程中不会遇到意外。
| 渠道 | 是否迁移 | 方式 |
|---|---|---|
| iOS 推送(APNs) | 是 | 我们导入您现有的设备 Token。它们会继续有效,因为 Token 属于您的 App 和您的 APNs 密钥,而不属于 OneSignal。 |
| Android 推送(FCM) | 是 | 同理:Token 属于您的 Firebase 项目。 |
| 华为推送(HMS) | 是 | 同理,使用您的 HMS 凭证。 |
| 邮件与短信订阅用户 | 是,需配置渠道 | 邮箱地址和电话号码会被导入。发送还需要在我们这边完成渠道配置:邮件需要一个通过 DKIM 验证的发信域名,短信需要发信方或服务商。我们会在首次发送前与您一起完成配置。 |
| Web 推送 | 否,改为重新订阅 | 浏览器订阅在密码学层面绑定了 OneSignal 的密钥,任何服务商都无法转移。您的订阅用户会以静默方式重新回归:详见 Web 推送章节。 |
| 消息历史、送达统计、Journey | 否 | 历史数据保留在 OneSignal 中。关闭账户前,请导出您想保留的所有报表。 |
| 分群(Segment)定义 | 重建,非导入 | OneSignal 的 API 只返回分群名称和数量,不返回筛选条件,所以没有可导入的内容。我们会在 Pushwoosh 中重新创建它们。 |
需要多长时间
SDK 替换和一次干净的测试发送,对一名开发者来说是一天的工作量。导入在我们这边并行进行,这正是保证您从第一天起就不损失触达能力的关键:在任何人更新 App 之前,导入的设备就已经可以送达。之后,您 App 自身的用户会随着新版本的安装节奏逐步迁移到 Pushwoosh SDK,这个过程需要几周时间,而且永远不会覆盖到最后一台设备。这正是导入环节存在的原因。
顺序很重要:
- 导出您的用户数据。 把您的 OneSignal app_id 和一个 App API key 发给我们,由我们自行拉取导出文件;或者您自己导出 CSV。详见下文。
- 发送您的推送凭证。 就是 OneSignal 目前用来发送推送的那些密钥。我们会在导入开始前完成上传,确保每一台导入的设备都可以被送达。
- 替换 SDK。 移除 OneSignal SDK,接入 Pushwoosh SDK,并用您的 Pushwoosh 应用代码和设备 API Token 完成初始化。各平台的具体步骤见下文版本 A 到 C。
- 验证送达。 在触碰生产流量之前,先注册一台测试设备并给自己发一条推送。
- 确认标签清单。 我们会根据您的导出文件生成清单;您只需划掉不再使用的标签,标出可能存储多个值的标签。我们负责导入并重建您的分群。
- 切换发送渠道。 测试送达确认无误、导入完成后,把您的推送活动指向 Pushwoosh,并停止从 OneSignal 发送。
2. 导出您的用户数据
方案 A(推荐):由我们代为完成。 把您的 OneSignal app_id 和一个 App API key 发给我们,由我们自行拉取导出文件。您这边的工作到此为止。
方案 B:自行操作。 在 OneSignal 中进入 Audience > Subscriptions,导出 CSV,或调用导出接口:
curl -X POST 'https://api.onesignal.com/players/csv_export?app_id=YOUR_APP_ID' \ -H 'Authorization: Key YOUR_APP_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"extra_fields":["external_user_id","timezone_id","notification_types"]}'响应会返回 csv_file_url,这是一个 gzip 压缩的 CSV 文件,三天内可下载。
文件中必须包含以下这些列,其余列可选,我们会忽略。
| 列 | 为什么需要它 |
|---|---|
identifier | 推送 Token 本身。缺少它的行无法迁移。 |
id | OneSignal 的订阅 id。它会成为我们这边的设备标识符。 |
device_type | 告诉我们平台类型:iOS、Android、华为、邮件、短信。 |
invalid_identifier | 标记已退订的行,我们会跳过它们。 |
tags | 您的自定义标签。我们会在 Pushwoosh 中重建它们。 |
external_user_id | 您自己的用户 id。一旦我们的 SDK 完成注册,它可以避免设备被重复创建。 |
timezone_id | 用于启用 Pushwoosh 的按时区发送(Send by Timezone)功能。 |
identifieriddevice_typeinvalid_identifiertagsexternal_user_idtimezone_id注意:external_user_id 和 timezone_id 不在默认导出范围内。请通过上文的 extra_fields 参数明确请求,或在控制台的列选择器中勾选。
3. 发送您的推送凭证
这些就是 OneSignal 目前代您发送推送所使用的凭证,不需要新建任何东西。我们无法从 OneSignal 中把它们取出来:一个已上传的密钥永远无法再次下载,所以这一步需要您来完成。
| 平台 | 我们需要什么 | 去哪里获取 |
|---|---|---|
| iOS | APNs Auth Key(.p8)、Key ID、Team ID、App bundle id | Apple Developer > Certificates, Identifiers & Profiles > Keys。不要吊销 OneSignal 正在使用的密钥;一个密钥可以同时服务于两边。 |
| Android | Firebase 服务账号 JSON(FCM v1) | Firebase Console > Project settings > Service accounts。必须是您 App 目前使用的同一个 Firebase 项目。 |
| 华为 | App ID 和 App Secret | AppGallery Connect > your project > App information。 |
我们会在导入开始前,把这些凭证上传到您的 Pushwoosh 应用中。这个顺序很重要:没有凭证的导入,只会产生一个塞满无法送达设备的数据库。
4. 检查您的标签和分群
标签会被迁移,您不需要自己盘点。 在 OneSignal 中,标签是没有声明类型的纯 key/value 字符串。在 Pushwoosh 中,每个标签需要先在应用层面声明一次类型(String、Integer、Boolean、Date、List 或 Price),之后才能承载具体的值。
拿到您的导出文件后,我们会立刻发给您一份基于文件本身生成的标签审核清单。清单列出我们发现的每一个标签,并填好了数据:示例值、有多少设备携带该值,以及我们建议的类型。您需要处理的只有两列:划掉不再使用的标签,标出可能同时存储多个值的标签。其余部分都是可以直接确认的建议方案。
我们选择询问而不是猜测的原因:标签的类型一旦创建就固定不变,所以如果一个多值标签被我们建成了纯 String 类型,就必须删除后重新导入。在导出文件中看起来是单值的标签,恰恰是我们无法从数据本身判断出来的情况。如果没有收到您的反馈,我们会按推断出的类型导入所有标签,并告知您哪些是我们猜测的。
分群会被重建。 OneSignal 的 API 可以按分群筛选导出文件、列出您的分群名称,但不会返回背后的筛选条件,所以没有可导入的内容。有两条路径可选:
- 重建筛选条件(推荐)。 把您的分群列表连同筛选条件发给我们;截图也可以。我们会基于导入的标签重新创建它们。重建后的分群是动态的:会随着用户变化持续更新。
- 冻结当前成员名单。 我们按分群分别导出一次,并为每份文件打上标记标签,例如
os_segment = vip_users。速度快,但结果是一份不会自动更新的快照。
基于 OneSignal 自有行为数据(会话次数、游戏时长、Active Users、Engaged Users)构建的分群,在导入时无法复现,因为这些历史数据留在 OneSignal 中。它们在 Pushwoosh 中的对应分群,会在我们的 SDK 上线到您的 App 后开始积累数据。
5. 我们这边要做的事
- 创建并配置您的 Pushwoosh 应用,上传第 3 步中的凭证。
- 清洗导出文件:删除已退订的行和 Token 为空的行,把 OneSignal 的平台代码映射为我们的代码,转换标签,并把您的
external_user_id映射为我们的 User ID。 - 创建标签结构,然后分批导入用户,并逐批验证。
- 向一个小型对照组发送测试推送,并将结果与预期进行比对。
- 向您反馈:文件中共有多少订阅用户、导入了多少,以及每一行被跳过的原因。
6. 在下一个 App 版本中接入 Pushwoosh SDK
导入能让您现有的用户立刻可以被触达,但这只是一座桥,不是终点。只有接入 App 内部的 Pushwoosh SDK,才能在系统更新 Token 时(重装、恢复、系统升级)获取新 Token,注册迁移后才安装的新用户,并上报打开、应用内消息和卸载事件。
请在同一个版本中移除 OneSignal SDK。一个构建里的两个推送 SDK 会争抢同样的通知回调,这种组合我们没有测试过。在新版本发布期间保留 OneSignal 发送没有问题、也是预期内的;但在同一个构建里保留两个 SDK 则不行。各平台的具体步骤见下文版本 A 到 C。
7. Web 推送:您的订阅用户如何回归
Web 推送无法导入,这是一个硬性技术限制,不是 Pushwoosh 的选择。Web 推送订阅是用创建者的 VAPID 密钥对签名的,OneSignal 的私钥永远不会离开 OneSignal——他们自己的文档也标明,Web 订阅密钥仅供 OneSignal 自家 SDK 使用。任何服务商都无法导入另一个服务商的 Web 订阅。真正可行的方案是静默重新订阅:
- 移除 OneSignal 的代码片段,并显式注销它的 service worker。留着旧的 worker 不管,会导致两个 worker 在同一域名下互相争抢。
- 安装 Pushwoosh Web Push SDK,把我们的 service worker 放在您域名的根目录下。
- 用您的应用代码和设备 API Token(
apiToken)完成初始化,然后启用自动订阅(autoSubscribe: true,或调用Pushwoosh.subscribe())。没有 Token,SDK 的调用会返回 401。
回访用户会被静默重新订阅。浏览器保存的通知权限属于您的域名,而不属于您之前的服务商,因此不会再弹出第二次授权提示,用户也不会察觉任何变化。您的用户基数恢复速度,取决于用户回访的速度:通常大部分用户会在一周内回归,剩余的会在接下来一个月里陆续补齐。
有三种情况需要留意:
- 已屏蔽通知的访客无法被重新订阅。浏览器会拒绝,也不会再次弹出提示。他们会继续处于订阅之外,这是符合预期的结果。
- 曾在您网站上主动退订、但浏览器权限仍处于已授权状态的访客,会被静默重新订阅。这在技术上是有效的,但会带回那些主动离开的人。如果您有一份屏蔽名单(按您自己的用户 id 或邮箱),发给我们,我们会把这些用户排除在每一次推送活动之外。如果没有,我们建议改为通过用户主动点击(例如一个订阅铃铛或提示)来触发订阅,而不是自动完成。
- 如果您的 Web 推送之前跑在原服务商提供的子域名上,而不是您自己的域名上,权限归属于那个子域名。这部分订阅用户无法恢复,必须在您的网站上重新授权。规划切换之前,请先确认自己使用的是哪种配置。
8. 导入之后会发生什么
- 同一台设备可能会短暂出现两条记录。 导入的记录携带的是 OneSignal 的标识符;等我们的 SDK 在同一台设备上运行后,会用自己的标识符重新注册。旧记录会通过卸载检测,或系统自动的 90 天不活跃清理机制被移除。在这期间提供
external_user_id,可以让这两条记录归属于同一个用户档案。 - 失效 Token 会在您的第一次推送活动中被清理。 苹果和谷歌只有在真正发送消息时才会告知某个 Token 已失效,所以迁移后的第一次发送同时也会清理您的用户库。
- 您导入后的数量会低于 OneSignal 显示的计数。 已退订的行、Token 为空的行以及 Web 推送的行都会被有意排除。我们的报告会准确告诉您每一类各有多少条。
9. 具体操作路径
您这边每一项操作的具体路径,省得您在控制台里到处翻找。
| 任务 | 操作路径 |
|---|---|
| OneSignal:导出用户数据 | Audience > Subscriptions > 可选的分群筛选 > column picker > Export |
| OneSignal:App ID 和 API key | Settings > Keys & IDs。获取 App ID 和一个 App API key;导出请求会以 Authorization: Key <App API key> 的形式发送它。 |
| Apple:APNs Auth Key | developer.apple.com > Certificates, Identifiers & Profiles > Keys > + > Apple Push Notification service (APNs) > Continue > Register > Download。.p8 文件只能下载一次;Key ID 在同一个页面上,Team ID 在 Membership details 下面。 |
| Firebase:服务账号 JSON | console.firebase.google.com > your project > 齿轮图标 > Project settings > Service accounts > Generate new private key |
| 华为:App ID 和 App Secret | AppGallery Connect > My projects > your project > your app > Project settings > App information |
| Pushwoosh:应用代码和设备 API Token | Control Panel > your application > Settings > API Access。该 Token 必须拥有对应应用的权限。 |
| 您的网站:移除旧的 worker | 从网站根目录删除 OneSignal 的 service worker 文件,并注销正在运行的 worker:navigator.serviceWorker.getRegistrations().then(rs => rs.forEach(r => r.unregister())) |
Authorization: Key <App API key> 的形式发送它。navigator.serviceWorker.getRegistrations().then(rs => rs.forEach(r => r.unregister()))10 月 1 日前的检查清单
把这份清单留着随时对照,这里的每一项都不需要下载表单。
- 已把导出文件发给我们,或已提供 app_id 和 App API key 供我们自行拉取
- 已发送推送凭证:APNs 密钥、FCM 服务账号 JSON,如使用华为推送则包含 HMS 密钥
- 如果需要迁移邮件和短信订阅用户,已与我们完成渠道配置
- 已回传标签审核清单,已移除无用标签,已标出多值标签
- 已将分群筛选条件发给我们(截图也可以)用于重建
- 已在测试构建中接入 Pushwoosh SDK,并收到测试推送
- 导入已完成,已查看我们的导入与跳过报告
- 如使用 Web 推送,Web Push SDK 已上线,旧的 service worker 已注销
- 生产构建上的测试送达确认无误
- 发送已切换到 Pushwoosh,OneSignal 的发送已停止
版本 A:原生 iOS 和 Android
iOS。 接入 Pushwoosh iOS SDK,然后在 Info.plist 中设置两个键:Pushwoosh_APPID 填写您的 Pushwoosh 应用代码,PW_API_TOKEN 填写您的设备 API Token。在您目前触发 OneSignal 授权提示的位置调用 registerForPushNotifications(),并参考 iOS 快速入门文档获取对应 SDK 版本的准确初始化代码。移除 OneSignal SDK 及其注册调用,避免两者同时请求 Token。
Android。 接入 com.pushwoosh:pushwoosh-firebase 依赖,然后在 AndroidManifest.xml 的 <application> 标签内添加两个 meta-data 条目:com.pushwoosh.appid 填写您的应用代码,com.pushwoosh.apitoken 填写您的设备 API Token。在初始化逻辑中调用 Pushwoosh.getInstance().registerForPushNotifications()。您的 Firebase 配置保持不变,google-services.json 仍留在项目中;FCM 凭证则填写到 Control Panel 中对应的 Android 平台配置里。
在您原来调用 OneSignal 对应方法的位置,用 setTags() 设置标签、用 setUserId() 设置用户标识符,这样替换完成后分群功能可以继续正常工作。
版本 B:Flutter 和 FlutterFlow
FlutterFlow 已经封装了 Pushwoosh Flutter SDK,所以这次迁移大部分是配置工作,而不是写代码。
- 在项目中把 Pushwoosh Flutter 包添加为自定义依赖。
- 在一个自定义 action 中,用您的应用代码初始化 SDK 并注册推送通知,具体以 Flutter 快速入门文档中当前的初始化 API 为准。
- 按照任何 Flutter App 的通用方式设置原生凭证:iOS 在
Info.plist中设置Pushwoosh_APPID和PW_API_TOKEN,Android 在AndroidManifest.xml中设置com.pushwoosh.appid和com.pushwoosh.apitoken。 - 移除 OneSignal 的集成,避免两个 SDK 同时注册。
- 在自定义 action 中用
setTags()和setUserId()映射标签和用户 id。
版本 C:React Native
- 安装插件:
npm install pushwoosh-react-native-plugin --save,iOS 还需执行pod install。 - 在根组件中完成初始化和注册:
import Pushwoosh from 'pushwoosh-react-native-plugin';
Pushwoosh.init({ pw_appid: "YOUR_APPLICATION_CODE" });Pushwoosh.register();- 在原生层添加设备 API Token:iOS 在
Info.plist中设置PW_API_TOKEN,Android 在AndroidManifest.xml中以 meta-data 形式设置com.pushwoosh.apitoken。Android 端google-services.json仍保留在项目中——FCM 凭证本身存放在 Control Panel 中。 - 移除 OneSignal 的 React Native 包及其初始化调用。
- 用插件 API 提供的
setTags()和setUserId(),把标签和用户 id 迁移过来。
联系我们的团队,获取迁移协助。
常见问题
任何阶段有疑问,都可以联系您在 Pushwoosh 的入驻对接人。我们更希望在导入之前解答清楚,而不是在导入之后核对数字。