如何使用Ionic+Capacitor通过Amazon SNS注册推送通知
Ionic + Capacitor 对接 Amazon SNS 推送全指南
1. PushNotifications.register() 方法的实际作用
这个方法不会直接返回可用于SNS的推送令牌,它的核心逻辑是三个:
- 触发系统级推送权限弹窗,向用户申请通知展示、角标更新、静默推送等相关权限
- 向设备所属平台的官方推送服务发起注册请求:iOS端对接APNs(苹果推送通知服务)申请设备令牌,Android端对接FCM(Firebase云消息传递,无GMS环境会自动尝试 fallback 到设备厂商自有推送通道)申请注册令牌
- 注册流程完成后触发
registration事件,事件回调携带的token字段,就是后续要传给Amazon SNS的平台端点令牌
注意:不要在App启动页直接调用这个方法弹权限申请,最好放在用户触发明确的「开启推送」操作、或者用户完成核心新手流程后调用,权限申请通过率会高很多。
2. 仅使用Amazon SNS是否需要配置Firebase与APNs
必须配置,不存在绕开的可能:
Amazon SNS本身只是推送分发的中转调度层,没有自己的系统级推送长连接通道。最终给iOS设备推消息必须走APNs,给海外发行的Android设备推消息必须走FCM,国内发行的Android设备要走对应厂商的自有推送通道,SNS只是帮你代管不同平台的推送密钥、统一分发请求而已。
如果不配置APNs/FCM,你根本拿不到合法的设备推送令牌,SNS也没有路径能把消息送达用户设备。
3. 完整对接实现步骤
3.1 前置平台配置
- iOS端配置
- 登录苹果开发者后台,给对应App ID开启
Push Notifications能力,优先生成.p8格式的APNs鉴权密钥(比传统证书方便,没有过期时间),如果用证书要注意区分开发沙箱、生产环境两套证书 - 打开Capacitor生成的Xcode工程,在
Signing & Capabilities页添加Push Notifications能力,同时勾选Background Modes下的Remote notifications选项 - 登录Amazon SNS后台,创建对应iOS平台的推送应用,上传APNs密钥/证书,注意沙箱、生产环境要分开创建两个应用,不能混用
- 登录苹果开发者后台,给对应App ID开启
- Android端配置
- 登录Firebase控制台创建项目,给对应App添加Android应用,下载
google-services.json文件放到Capacitor Android工程的app/目录下 - 调整Android工程的
build.gradle配置,添加Google Services插件依赖,确保FCM可以正常初始化 - 登录Amazon SNS后台创建Android平台的推送应用,上传Firebase控制台生成的FCM服务账号鉴权信息
- 如果是面向国内应用市场发行,需要额外对接华为、小米、OPPO、vivo等厂商的推送SDK,SNS后台支持上传对应厂商的推送密钥,不需要自己做通道适配
- 登录Firebase控制台创建项目,给对应App添加Android应用,下载
3.2 前端代码实现
首先安装官方推送插件:
npm install @capacitor/push-notifications npx cap sync
核心业务逻辑代码,要等Capacitor平台初始化完成后再调用:
import { PushNotifications, Token } from '@capacitor/push-notifications'; import { Capacitor } from '@capacitor/core'; // 检查并申请推送权限 const checkPushPermission = async () => { let permStatus = await PushNotifications.checkPermissions(); if (permStatus.receive === 'prompt') { permStatus = await PushNotifications.requestPermissions(); } if (permStatus.receive !== 'granted') { console.log('用户未授予推送权限'); return; } // 权限通过后再发起注册 await PushNotifications.register(); }; // 注册推送相关监听 const addPushListeners = () => { // 注册成功拿到令牌 PushNotifications.addListener('registration', async (token: Token) => { const deviceToken = token.value; const platform = Capacitor.getPlatform(); // 把令牌和平台类型传给自有服务端,由服务端对接SNS创建/更新平台端点 // 禁止前端直连SNS接口,避免密钥泄露 await fetch('/your-business-api/save-push-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token: deviceToken, platform }) }); }); // 监听注册错误,方便排查问题 PushNotifications.addListener('registrationError', (err) => { console.error('推送注册失败:', err.error); }); // 可选:监听前台推送到达事件 PushNotifications.addListener('pushNotificationReceived', (notification) => { console.log('前台收到推送:', notification); }); // 可选:监听推送点击事件,做页面跳转等业务逻辑 PushNotifications.addListener('pushNotificationActionPerformed', (action) => { console.log('用户点击推送:', action.notification); }); }; // 对外暴露初始化方法,在App启动逻辑里调用 export const initPushService = async () => { // web环境不支持原生推送,直接跳过 if (!Capacitor.isNativePlatform()) return; addPushListeners(); await checkPushPermission(); };
4. 实用避坑技巧
- iOS端APNs沙箱、生产环境的令牌完全不通用:debug调试包拿到的是沙箱令牌,TestFlight、App Store正式包拿到的是生产令牌,传给SNS的时候要对应匹配环境的应用,混传会直接导致推送失败
- 推送令牌不是永久有效的:系统会在App重装、系统重置、通道策略调整的时候刷新令牌,不要只在用户首次打开App的时候传一次令牌,每次冷启动都要对比本地缓存的令牌和当前拿到的新令牌,不一致就重新传给服务端更新SNS端点
- 所有SNS交互逻辑必须放在服务端实现:前端存储SNS的访问密钥会有严重的泄露风险,可能被恶意调用盗刷云服务额度
- 测试优先用SNS控制台的单发测试功能:拿到设备令牌后先在控制台手动发测试消息,确认单设备通道连通后再做批量推送逻辑,排查问题效率更高
- Android 13及以上版本必须动态申请
POST_NOTIFICATIONS权限,记得在AndroidManifest.xml里声明该权限,否则不会弹出权限申请弹窗
内容的提问来源于stack exchange,提问作者Jordin Vell
相关产品推荐
相关产品推荐

