如何在Cordova应用中获取OneSignal用户ID?授权推送权限后仍无法获取ID的问题咨询
解决OneSignal授权后无法获取设备ID/UserId的问题
我来帮你排查这个问题!你遇到的情况其实很常见——权限请求成功但拿不到设备ID,大概率是因为调用时机不对,或者没有监听OneSignal提供的正确回调事件。咱们一步步来解决:
核心问题:异步时机不匹配
你当前的代码里,getIds是在deviceready触发后直接调用的,但这时候可能存在两种情况:
- 用户还没完成权限授权,OneSignal还没完成订阅流程
- OneSignal的初始化和设备ID获取是异步的,你调用
getIds时ID还没生成或同步完成
解决方案1:把getIds放到权限授权回调里
当用户点击授权弹窗后,再去获取设备ID,这时候订阅流程已经完成,ID肯定已经准备好了:
document.addEventListener('deviceready', OneSignalInit, false); function OneSignalInit() { window.plugins.OneSignal.setAppId("xxxxxxxxxxxxx"); window.plugins.OneSignal.setNotificationOpenedHandler(function(jsonData) { console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData)); }); // 在用户授权回调里获取ID window.plugins.OneSignal.promptForPushNotificationsWithUserResponse(function(accepted) { console.log("User accepted notifications: " + accepted); if (accepted) { window.plugins.OneSignal.getIds(function(ids) { alert("player id: " + ids.userId); console.log("push token: " + ids.pushToken); // 顺便可以拿到推送令牌 }); } }); }
解决方案2:监听subscriptionChange事件(更可靠)
OneSignal提供了subscriptionChange观察者事件,只要用户的订阅状态发生变化(包括首次授权成功、取消订阅后重新授权),都会触发这个事件,这是获取ID最稳妥的方式:
document.addEventListener('deviceready', OneSignalInit, false); function OneSignalInit() { window.plugins.OneSignal.setAppId("xxxxxxxxxxxxx"); window.plugins.OneSignal.setNotificationOpenedHandler(function(jsonData) { console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData)); }); // 监听订阅状态变化 window.plugins.OneSignal.setSubscriptionObserver(function(stateChanges) { console.log("订阅状态变化: ", stateChanges); // 当用户成功订阅且userId存在时获取 if (stateChanges.to.subscribed && stateChanges.to.userId) { alert("player id: " + stateChanges.to.userId); } }); window.plugins.OneSignal.promptForPushNotificationsWithUserResponse(function(accepted) { console.log("User accepted notifications: " + accepted); }); }
解决方案3:处理用户已授权过的情况
如果用户之前已经授权过推送权限,promptForPushNotificationsWithUserResponse不会再弹出授权框,这时候你需要先检查当前订阅状态,再获取ID:
document.addEventListener('deviceready', OneSignalInit, false); function OneSignalInit() { window.plugins.OneSignal.setAppId("xxxxxxxxxxxxx"); window.plugins.OneSignal.setNotificationOpenedHandler(function(jsonData) { console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData)); }); // 先检查当前是否已订阅 window.plugins.OneSignal.getSubscription(function(status) { if (status.subscribed) { // 已订阅直接获取ID window.plugins.OneSignal.getIds(function(ids) { alert("Existing player id: " + ids.userId); }); } else { // 未订阅则请求权限 window.plugins.OneSignal.promptForPushNotificationsWithUserResponse(function(accepted) { console.log("User accepted notifications: " + accepted); }); } }); // 同时监听订阅变化,覆盖所有场景 window.plugins.OneSignal.setSubscriptionObserver(function(stateChanges) { if (stateChanges.to.subscribed && stateChanges.to.userId) { alert("player id: " + stateChanges.to.userId); } }); }
额外排查步骤
- 更新OneSignal插件:旧版本可能存在兼容性问题,执行命令更新:
cordova plugin update onesignal-cordova-plugin
- 开启调试日志:添加日志代码,查看是否有错误信息:
window.plugins.OneSignal.setLogLevel(6, 0); // 开启详细日志,方便排查问题
内容的提问来源于stack exchange,提问作者drago
相关产品推荐
相关产品推荐

