You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:27:48