簡體   English   中英

如何正確發送推送通知

[英]how to properly send push notifications

這不是我第一個發送推送通知的應用程序,但它是我第一個同時向所有用戶發送通知的應用程序。

我所經歷的是,並非我的所有用戶都收到通知,只有其中一些用戶收到通知,即使他們的設置正確(即啟用了我的應用程序的通知),代碼也是正確的,因為它已發送給其中一些,所以我的猜測是代碼“錯過”了一些執行,因為與 APNS 的連接是異步的,所以不知何故(如果我錯了,你告訴我)它弄亂了發送通知的隊列。

這是代碼:

function sendNotification(){

$sql = "SELECT * FROM users WHERE phone = 'iPhone' AND pushID != ''";
try {
    $db = getConnection();
    $stmt = $db->prepare($sql);  
    $stmt->execute();
    $users = $stmt->fetchAll(PDO::FETCH_OBJ);

    $request = Slim::getInstance()->request();
    $content = json_decode($request->getBody());
    $message = $content->message;

    foreach($users as $user){

            // Put your device token here (without spaces):
            $deviceToken = $user->pushID;


            // Put your private key's passphrase here:
            $passphrase = 'xxxxxxx';

            ////////////////////////////////////////////////////////////////////////////////

            $ctx = stream_context_create();
            stream_context_set_option($ctx, 'ssl', 'local_cert', 'xxxxx.pem');
            stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

            // Open a connection to the APNS server
            $fp = stream_socket_client(
                'ssl://gateway.push.apple.com:2195', $err,
                $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

            if (!$fp)
                exit("Failed to connect: $err $errstr" . PHP_EOL);

            echo 'Connected to APNS' . PHP_EOL;

            // Create the payload body
            $body['aps'] = array(
                'alert' => $message,
                'sound' => 'default'
                );

            // Encode the payload as JSON
            $payload = json_encode($body);

            // Build the binary notification
            $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

            // Send it to the server
            $result = fwrite($fp, $msg, strlen($msg));

            if (!$result)
                echo 'Message not delivered' . PHP_EOL;
            else
                echo 'Message successfully delivered' . PHP_EOL;

            // Close the connection to the server
            fclose($fp);

    }
    $db = null;
} catch(PDOException $e) {
    echo '{"error":{"text":'. $e->getMessage() .'}}'; 
}
}

如您所見,我使用 iPhone 獲取所有用戶並向他們發送通知。 我的手機是該列表中的最后一個用戶,但我沒有得到它,我認識的另一個用戶是最早的用戶之一,她得到了它。 它要么錯過了數組中的一些用戶,要么只執行前半部分,不顯示錯誤。

我為此使用了 Slim。

希望你能幫助我,謝謝!

您發送到的某些設備令牌可能無效。 即使是一台無效的設備也可以解釋您所遇到的情況。 當您發送帶有無效設備令牌的通知時,Apple 會返回錯誤響應並關閉套接字。

有可能當您的代碼檢測到套接字已關閉時,您已經在無效通知之后發送了許多通知(甚至可能您在檢測到套接字關閉之前已發送完所有通知),這會導致所有通知在無效的將被丟棄。 創建新套接字后,此類通知必須重新發送給 Apple。

我建議您閱讀本文檔中Push Notification Throughput and Error Checking部分以獲取更多詳細信息。

確保您的數據庫不包含生產設備令牌和沙箱設備令牌的混合,因為生產令牌在沙箱環境中無效,反之亦然。

您可以使用此方法使用以下代碼向多個用戶發送通知。 以下代碼可幫助您發送Firebase 推送通知 android 您需要將服務器密鑰和消息傳遞給此函數。

<?php
$target = ["TARGET_ID"];

$notificationBody['data'] = [
    'type' => 1,
    'url' => "https://trinitytuts.com/wp-content/uploads/2018/07/macaw.png",
    'title' => "title",
    "msg" => "Message"
];

$response = sendMessage($notificationBody, $target, $_POST['serverKey']);

function sendMessage($data, $target, $serverKey){
    //FCM api URL
    $rsp = [];
    $url = 'https://fcm.googleapis.com/fcm/send';
    //api_key available in Firebase Console -> Project Settings -> CLOUD MESSAGING -> Server key
    $server_key = $serverKey;
    $fields = array();
    $fields['data'] = $data;
    if(is_array($target)){
            $fields['registration_ids'] = $target;
        }else{
            $fields['to'] = $target;
    }
    //header with content_type api key
    $headers = array(
        'Content-Type:application/json',
        'Authorization:key='.$server_key
    );

    $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($fields));
    $result = curl_exec($ch);
    if ($result === FALSE) {
        //die('FCM Send Error: ' . curl_error($ch));
    }
    curl_close($ch);

    //print_r($result);
    return $result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM