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

基于MySQLi Multi_Query的PHP API接收JSON发送FCM推送遇异常

实现PHP API向Android用户发送推送通知的完整方案

我来帮你一步步拆解需求,从接收JSON数据到最终发送FCM推送,同时避开常见的坑:

1. 接收并验证请求的JSON数据

首先得确保API能正确接收前端传来的JSON,还要验证必填字段是否存在,避免后续逻辑出错:

// 接收JSON请求体
$input = file_get_contents('php://input');
$data = json_decode($input, true);

// 验证必填字段:手机号、状态、用户ID
if (!isset($data['phone_number'], $data['status'], $data['user_id'])) {
    http_response_code(400);
    echo json_encode(['error' => '缺少必填参数:phone_number、status、user_id']);
    exit;
}

$phoneNumber = $data['phone_number'];
$status = $data['status'];
$userId = $data['user_id'];

2. 从数据库关联获取FCM令牌

接下来要通过number_list表找到对应手机号所属的用户(这里你传了user_id,也可以做双重验证),再从user表拿到有效的FCM令牌:

// 假设你用PDO连接数据库(推荐用PDO避免SQL注入)
$dbHost = '你的数据库地址';
$dbName = '数据库名';
$dbUser = '用户名';
$dbPass = '密码';

try {
    $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 关联两张表查询,确保手机号和user_id匹配,且用户开启了FCM
    $stmt = $pdo->prepare("
        SELECT u.fcm, u.fcm_enabled 
        FROM number_list nl
        JOIN user u ON nl.user_id = u.id
        WHERE nl.number = :phone AND nl.user_id = :user_id
    ");
    $stmt->bindParam(':phone', $phoneNumber);
    $stmt->bindParam(':user_id', $userId);
    $stmt->execute();
    $userInfo = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$userInfo) {
        http_response_code(404);
        echo json_encode(['error' => '未找到对应手机号的用户记录']);
        exit;
    }

    // 检查用户是否开启FCM推送
    if (!$userInfo['fcm_enabled']) {
        http_response_code(403);
        echo json_encode(['error' => '该用户未开启推送通知']);
        exit;
    }

    $fcmToken = $userInfo['fcm'];
    if (empty($fcmToken)) {
        http_response_code(400);
        echo json_encode(['error' => '该用户的FCM令牌为空']);
        exit;
    }
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['error' => '数据库查询失败:' . $e->getMessage()]);
    exit;
}

3. 调用FCM API发送推送通知

现在拿到有效的FCM令牌,就可以根据status字段定制通知内容,调用FCM的HTTP API发送推送:

// FCM服务器密钥(从Firebase控制台获取)
$fcmServerKey = '你的FCM服务器密钥';

// 根据状态定制通知内容
switch ($status) {
    case 'active':
        $notificationTitle = '手机号状态更新';
        $notificationBody = '你的手机号已激活,可以正常使用啦!';
        break;
    case 'inactive':
        $notificationTitle = '手机号状态提醒';
        $notificationBody = '你的手机号已暂停使用,请及时处理';
        break;
    // 可以添加更多状态的处理逻辑
    default:
        $notificationTitle = '状态更新';
        $notificationBody = '你的手机号状态已变更为:' . $status;
        break;
}

// 构造FCM请求体
$fcmPayload = [
    'to' => $fcmToken,
    'notification' => [
        'title' => $notificationTitle,
        'body' => $notificationBody,
        'sound' => 'default' // 可选:播放默认通知音
    ],
    'data' => [
        'phone_number' => $phoneNumber,
        'status' => $status,
        'user_id' => $userId
        // 可以添加更多自定义数据,供Android客户端处理
    ]
];

// 发送请求到FCM API
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: key=' . $fcmServerKey,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fcmPayload));

$fcmResponse = curl_exec($ch);
$curlError = curl_error($ch);
curl_close($ch);

if ($curlError) {
    http_response_code(500);
    echo json_encode(['error' => 'FCM请求失败:' . $curlError]);
    exit;
}

// 解析FCM响应,判断是否发送成功
$fcmResponseData = json_decode($fcmResponse, true);
if (isset($fcmResponseData['failure']) && $fcmResponseData['failure'] > 0) {
    http_response_code(500);
    echo json_encode(['error' => '推送发送失败:' . json_encode($fcmResponseData['results'])]);
} else {
    echo json_encode(['success' => true, 'message' => '推送通知已成功发送']);
}

常见异常排查要点

  • SQL注入风险:一定要用预处理语句(PDO或MySQLi的prepare),不要直接拼接SQL字符串
  • FCM令牌有效性:如果FCM返回InvalidRegistration错误,说明令牌无效,需要提醒用户重新登录获取新令牌
  • 数据库关联错误:确保number_list表的user_id和user表的id是正确关联的,避免查询不到数据
  • 请求头设置:FCM API要求必须带Authorization和Content-Type头,缺一不可

内容的提问来源于stack exchange,提问作者Khushi Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:59:13