使用 Laravel 和 Firebase 消息传递发送大量通知时出现 504 超时错误

问题描述 投票:0回答:1

我同时向许多用户发送通知,这是我的代码:

public function sendNotifications($title, $body, $image)
{
    $SERVER_API_KEY = "my_api_key";
       
    $tokens = DB::select("select * from fcm_token");
    $token_array = [];
    for ($i = 0; $i < count($tokens); $i++) {
        array_push($token_array, $tokens[$i]->token);
    }
       
    $data = [
        "registration_ids" => $token_array,
        "notification" => [
            "title" => $title,
            "body" => $body,
            "image" => $image,
            "sound" => "default" // required for sound on ios
        ],
    ];
    $dataString = json_encode($data);
        
    $headers = [
        'Authorization: key=' . $SERVER_API_KEY,
        'Content-Type: application/json',
    ];
        
    $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, $headers);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
    $response = curl_exec($ch);
    curl_close($ch);
}

此函数在管理员填写表单后执行,管理员应将标题正文和图像提供给后端。之后,他们必须等待任务完成(以确保每个人都收到通知)。以前它工作得很好,但现在经过很长的加载时间后,服务器响应 504 超时。

我知道我可以排队,但这能解决问题吗?队列不会也会因同样的错误而停止吗?

我将应用程序托管在共享托管 (lws) 中,我的最大执行时间是 60 秒,并且如果不支付更多费用就无法增加它。我想在花更多钱之前先确定问题出在哪里。

我尝试只用 100 个用户来测试它,它的工作就像一个魅力,但我需要将其发送到更多用户,因为我的用户超过 4000 个。

php laravel curl firebase-cloud-messaging http-status-code-504
1个回答
1
投票

Google Cloud 消息传递支持一次发送到 1000 个令牌。

$tokens = array_chunk($all_tokens, 1000);

foreach ($tokens as $thousand_tokens) {
     send_notification(
         $thousand_tokens,
         $request->title . ' Video added',
         'New Video added in ' . $cat->category->name,
         $cat->image_url,
         $data
     );
 }

上面是示例代码。您可以使用它来修改您的代码。

function send_notification($tokens, $message, $description, $image, $data)
{
    try {
        $token_ids = array($tokens);
        $apiKey = env('FCM_KEY');
        $url = 'https://fcm.googleapis.com/fcm/send';

        $msg = array(
            "registration_ids" => $tokens,
            "collapseKey" => "com.notification",
            "data" => $data,
            "notification" => array(
                "android" => array(
                    "channelId" => "Notifications-Channel",
                    "imageUrl" => $image,
                    "sound" => "sample.mp3"
                ),
                "sound" => "sample.mp3",
                "channelId" => "Notifications-Channel",
                "android_channel_id"=> "Notifications-Channel",
                "body" => $description,
                "title" => $message
            )
        );
        
        define("GOOGLE_API_KEY", $apiKey); 
        $headers = array(
            'Authorization: key=' . $apiKey,
            'Content-Type: application/json'
        );
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($msg));
        $result = curl_exec($ch);
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }
        curl_close($ch);
        return $result;
    } catch(Exception $e) {
        return 'at exception ' . $e->getLine();
        die('Error: ' . $e->getMessage());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.