[英]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.