如何获取OneSignal Web通知的user_id及无Composer的PHP发送方法
问题解答
1. 获取OneSignal用户唯一ID(player_id)的正确方法
OneSignal Web SDK中,player_id就是用户的唯一标识,你提到的subscriber_id和player_id是同一概念(Web平台下两者等价)。获取的核心是在SDK初始化完成后调用对应方法,同时处理用户未订阅的场景:
方法一:初始化完成后直接获取
在现有初始化代码中扩展,确保SDK加载就绪后获取ID:
<script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script> <script> window.OneSignalDeferred = window.OneSignalDeferred || []; OneSignalDeferred.push(function(OneSignal) { OneSignal.init({ appId: "YOUR_APP_KEY", }); // 初始化完成后获取player_id OneSignal.getUserId().then(function(playerId) { if (playerId) { // 拿到ID后,可通过AJAX提交到后端绑定用户账号 console.log("Player ID:", playerId); fetch('/api/save-player-id', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({player_id: playerId, user_id: "当前登录用户ID"}) }); } else { // 用户未授权通知权限,可引导开启 console.log("用户未订阅通知"); } }); }); </script>
方法二:监听订阅状态变化
如果用户后续才开启通知权限,通过事件监听实时获取ID:
OneSignal.on('subscriptionChange', function(isSubscribed) { if (isSubscribed) { OneSignal.getUserId().then(function(playerId) { console.log("用户订阅成功,Player ID:", playerId); // 同步到后端存储 }); } });
注意:只有用户允许通知权限后,才能获取到有效的player_id,否则返回null。
2. 不使用Composer的PHP发送通知优化方案
你提供的代码缺少OneSignal API必需的授权头,以下是修正并优化后的版本,包含错误处理和参数完善:
// 调用示例 $sendResult = sendNotification("订单通知", "您的订单已发货", "目标player_id"); print_r($sendResult); function sendNotification($title, $message, $playerId, $image = "", $webUrl = "") { // 替换为你的OneSignal App ID和REST API密钥(控制台Settings > Keys & IDs中获取) $appId = "YOUR_APP_ID"; $restApiKey = "YOUR_REST_API_KEY"; $content = [ "en" => $message ]; $headings = [ "en" => $title ]; $fields = [ "app_id" => $appId, "include_player_ids" => [$playerId], "contents" => $content, "headings" => $headings, "data" => ["order_id" => "12345"], // 自定义业务数据,可选 ]; // 可选参数:添加跳转链接和通知图片 if (!empty($webUrl)) { $fields["web_url"] = $webUrl; } if (!empty($image)) { $fields["chrome_web_image"] = $image; $fields["firefox_web_image"] = $image; // 兼容多浏览器 } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://onesignal.com/api/v1/notifications"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json; charset=utf-8", "Authorization: Basic {$restApiKey}" // 必须添加的授权头 ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 建议开启SSL验证,提升安全性 $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($response === false) { $error = curl_error($ch); curl_close($ch); return ["success" => false, "error" => $error]; } curl_close($ch); $responseData = json_decode($response, true); // 根据返回状态判断是否发送成功 if ($httpCode === 200 && isset($responseData["id"])) { return ["success" => true, "notification_id" => $responseData["id"]]; } else { return ["success" => false, "response" => $responseData]; } }
关键修正说明:
- 新增
Authorization请求头,这是调用OneSignal API的必填参数 - 增加了错误捕获和状态返回,方便排查问题
- 保留了可选参数的灵活性,支持自定义跳转链接和通知图片
- 建议开启
CURLOPT_SSL_VERIFYPEER,避免不安全的请求
内容的提问来源于stack exchange,提问作者P.Coder
相关产品推荐
相关产品推荐

