I am able to connected to the apns and by inserting the values to database for just check i am getting "message delivered" message but it's not showing any notification....can anybody tell me where i am mistaken...
$deviceToken = '**********************';
$payload['aps'] = array('alert' => 'This is the alert text', 'badge'
=> 1, 'sound' => 'default'); $payload = json_encode($payload);
$passphrase = '***';
$apnsHost = 'gateway.sandbox.push.apple.com'; $apnsPort = 2195; $apnsCert = 'ck.pem';
$streamContext = stream_context_create(); stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert); stream_context_set_option($streamContext, 'ssl', 'passphrase',$passphrase );
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if (!$apns)
{
$check = $errorString; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query); } else{
$check = "connected"; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query); }
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;
//chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
$result=fwrite($apns, $apnsMessage);
if (!$result)
{
$check = 'Message not delivered' ; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query);
} else { $check = 'Message delivered' ; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query);
}
enter code here
fclose($apns);
$apnsHost = 'gateway.sandbox.push.apple.com';
remove sandbox from this url and it will run...
i have tested it...
Make sure that :
1-your app is not running because push notification used only to notify the use when the app is closed.
2-Device token of the device is correct Also make sure that the push notification certificate is also configured for the same device.
3-Make sure that you device is connected to the internet .
You can take a look at this link.
Push Notification
Related
I've set up and APNS Provider Server using PHP. I connect to Apple's APNS Server with no errors, and the script seems to run fine, cycling through all the devices and sending the payload. However, notifications aren't being received on the devices that have subscribed to notifications. Can someone please help me find the error in my code?
$message = $_POST['message'];
echo "Posted Message: $message<br />";
$message = str_replace("'", "\'", $message);
echo "Formatted message: $message<br />";
$title = $_POST['title'];
$title = str_replace("'", "\'", $title);
echo "Formatted Title: $title<br />";
$category = $_POST['category'];
echo "Category: $category<br />";
$alert = array('title' => "$title", 'body' => "$message");
foreach ($alert as $key => $value){
echo "Key: $key Value: $value<br />";
}
ini_set("display_errors",1);
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apns.pem';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if ($error!="" || $errorString!=""){
echo "Error Connecting: $error : $errorString<br />";
}
else{
echo "No Error Connecting<br />";
}
$query = "INSERT INTO notifications (`title`, `message`, `category`) VALUES (\"$title\", \"$message\", \"$category\")";
echo "Insert Query: $query<br />";
$result1 = mysqli_query($connection, $query);
$query = "SELECT * FROM notifications ORDER BY notification_id DESC";
$result931 = mysqli_query($connection, $query);
$row = $result931->fetch_assoc();
$notification_id = $row[notification_id];
$query = "SELECT * FROM category_subscriptions WHERE category_id='$category' ORDER BY device_id";
$result1 = mysqli_query($connection, $query);
echo "Subscriber Query: $query<br />";
while($row = $result1->fetch_assoc()) {
$device_id = $row[device_id];
$query = "SELECT * FROM devices WHERE device_id='$device_id' ORDER BY device_id";
$result = mysqli_query($connection,$query);
while($r = $result->fetch_assoc()) {
$deviceToken = $r[device_token];
$badge = $r[badge_value] + 1;
if ($r[accepts_alerts]==1) {
if ($r[accepts_badges]==1) {
if ($r[accepts_sounds]==1) {
$payload['aps'] = array('alert' => $alert, 'badge' => $badge, 'sound' => 'default');
} else {
$payload['aps'] = array('alert' => $alert, 'badge' => $badge);
}
}
else if ($r[accepts_sounds]==1) {
$payload['aps'] = array('alert' => $alert, 'sound' => 'default');
}
else {
$payload['aps'] = array('alert' => $alert);
}
$payload1 = json_encode($payload);
echo "Payload: $payload1<br />";
echo "<br /> Sending to Device Token: $deviceToken<br />";
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload1)) . $payload1;
echo "APNS Message: $apnsMessage<br />";
fwrite($apns, $apnsMessage);
$query6 = "UPDATE devices SET badge_value = $badge WHERE device_id='$device_id'";
$result6 = mysqli_query($connection,$query6);
$query7 = "INSERT INTO notification_map (`device_id`, `notification_id`, `viewed`) VALUES ($device_id, $notification_id, \"false\")";
$result7 = mysqli_query($connection,$query7);
}
}
}
fclose($apns);
Screenshot:
Perform following steps:
1. Check if pem file is valid or not.
2. check if port 2195 is open on your server or not.
3. if your pem file is of development mode the use "ssl://gateway.sandbox.push.apple.com:2195" to connect to apns otherwise if your pem file is of production mode the use "ssl://gateway.push.apple.com:2195" .
check if passpharas is correct.
check this sample code:
<?php
// Put your device token here (without spaces):
$deviceToken = 'fefb03ba6adcea310cf3f455dae16fec4f63b4ba4d96103c20d594a04efd7c2a';
// Put your private key's passphrase here:
$passphrase = 'Welcome#1';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.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',
'title' => 'testing title'
);
// 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);
Upon further reading of the documentation, I believe I have figured out my problem. I had one database table that held the device tokens for both development and production versions of the app. Apparently when trying to send a production notification it was closing the connection after sending a development device token. I'm not sure why the fwrite command wasn't sending errors after the connection closed, but since I deleted the development device tokens from the database table, it appears to be working now.
I'm trying to push notification to APNS to update my pass in Apple Wallet app. According to this document, we only need to send the pass type identifier and the push token to APNs. Then they will take care of the rest.
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = base_path('app/config/passbook/certificates.pem');
$payload = ['aps' => []];
$payload = json_encode($payload);
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', 'xxxxxx');
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if(!$apns) {
Logger::logError(1, "Passbook push notification error", ['serial_number' => $serialNumber, 'pass_type_id' => $passIdentify]);
return "Failed to connect (stream_socket_client): $error $errorString";
} else {
foreach($push_tokens as $idx => $push_token) {
$msg = chr(0) . pack('n', 32) . pack('H*', $push_token) . pack('n', strlen($payload)) . $payload;
fwrite($apns, $msg);
}
}
#socket_close($apns);
fclose($apns);
There is no error returned but it seem doesn't work. What do I do wrong? Please help.
This is the code working on my project
$errors = [];
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = base_path('app/config/passbook/certificates.pem');
$payload = ['aps' => []];
$payload = json_encode($payload);
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', 'xxxxxxxxx');
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
stream_set_blocking ($apns, 0);
if( ! $apns) {
return "Failed to connect (stream_socket_client): $error $errorString";
} else {
foreach($push_tokens as $idx => $push_token) {
$msg = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $push_token)) . chr(0) . chr(mb_strlen($payload)) . $payload;
$success = fwrite($apns, $msg);
if ($success === strlen($msg)) { // log success
Logger::logPassbook('Push success', ['push_token' => $push_token]);
} else {
Logger::logPassbook('Push failed', ['push_token' => $push_token]);
}
}
}
#socket_close($apns);
fclose($apns);
return $errors;
I have written a function to send push notifications to iOS devices. It sends pushes to more than 100 devices for now. However sometimes it is not sending push notifications. When I debug through the process I identified based on push notification the whole process fails. but the issues is all push tokens are in valid format. So my initial code was like this.
$certificatePath = CERTIFICATE_PATH . "/".APN_CERTIFICATE_FILE;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $certificatePath);
stream_context_set_option($streamContext, 'ssl', 'passphrase', APN_PASSWORD);
$apns = stream_socket_client(APN_HOST . ':' . APN_PORT , $error, $errorString, 2, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
if (!$apns) {
echo "Failed to connect $err $errstrn";
return false;
}
$payload = array();
$payload['aps'] = array('alert' =>$message,'title'=>$title, 'sound' => 'default','data'=>array());
$payload = json_encode($payload);
foreach ($pushTokens as $pushToken)
{
$pushToken = str_replace(' ', '', $pushToken);
if(!ctype_xdigit($pushToken))
continue;
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $pushToken)) . pack ("n",strlen($payload)) . $payload;
$rst = fwrite($apns, $apnsMessage);
}
fclose($apns);
As a fix I changed the code to different way. I know this code is expensive since it open and close connection for every push notification.
$certificatePath = CERTIFICATE_PATH . "/".APN_CERTIFICATE_FILE;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $certificatePath);
stream_context_set_option($streamContext, 'ssl', 'passphrase', APN_PASSWORD);
$payload = array();
$payload['aps'] = array('alert' =>$message,'title'=>$title, 'sound' => 'default','data'=>array());
$payload = json_encode($payload);
foreach ($pushTokens as $pushToken)
{
$apns = stream_socket_client(APN_HOST . ':' . APN_PORT , $error, $errorString, 2, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
if (!$apns) {
echo "Failed to connect $err $errstrn";
return false;
}
$pushToken = str_replace(' ', '', $pushToken);
if(!ctype_xdigit($pushToken))
continue;
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $pushToken)) . pack ("n",strlen($payload)) . $payload;
$rst = fwrite($apns, $apnsMessage);
fclose($apns);
}
I am wondering if it is an issue with fwrite or somewhere else. Appreciate if someone can help me with my first method as it is speed, and run with minimum resources.
Push notification badge count not increasing.It shows always 1.I have used php to send the push from server and here is the code following:
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsCert = 'project_dev.pem';
$apnsPort = 2195;
$badgecount=1;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if (!$apns){
exit("Failed to connect: $error $errorString" . PHP_EOL);
}else{
$messageHeader = (strlen($message) > 26) ? substr($message,0,26).'...' : $message;
$msgd=explode(':',$message);
$payload['aps'] = array('alert' => $messageHeader,'badge' => $badgecount, 'sound' => 'default','mess'=>$fromUserId.'||'.$userNamee.'||'.$userimage.'||'.$message,'type'=>'reply', 'unread_count'=>$unread_count);
$output = json_encode($payload);
$token = pack('H*', str_replace(' ', '', $token));
$apnsMessage = chr(0) . chr(0) . chr(32) . $token . chr(0) . chr(strlen($output)) . $output;
fwrite($apns, $apnsMessage);
fclose($apns);
}
badgecount always send by server side.it seems you are sending $badgecount=1; always.Update it with other value then check.It definitely reflect on IOS.
In your code you have send your badge always one that's why you getting only $badgecount 1 badge into application side.
you need to use following type to send notification badge.
$query = "SELECT badgecount FROM pushnotifications WHERE device_token = '{$device_token}'";
$query = $this->db->query($query);
$row = $query->row_array();
$updatequery = "update pushnotifications set badgecount=badgecount+1 WHERE device_token ='{$device_token}'";
$updatequery = $this->db->query($updatequery);
$device = $device_token;
$payload['aps'] = array('alert' => $pushmessage, 'badge' =>$row["badgecount"]+1, 'sound' => 'default');
$payload = json_encode($payload);
I think you now more clearify with above code.
This is the code that I am using for notification from PHP to iOS
#--------------- initializations ------------------------------
$message = substr($message, 0, 255);
$sound = 'default';
$development = true;
$badge = '1';
$payload['aps'] = array(
'alert' => $message,
'badge' => intval($badge),
'sound' => $sound
);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
#-------------------------(/initializations)---------------
// developement or live server certificate
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = __DIR__.'/app_dev.pem';
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = __DIR__.'/app_prod.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_CONNECT, $stream_context);
$device_tokens = $receivers;
foreach($device_tokens as $device_token)
{
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
$result = fwrite($apns, $apns_message,strlen($apns_message));
}
#socket_close($apns);
fclose($apns);
The error I am getting is
Warning: stream_socket_client(): unable to connect to
ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)
Can anybody see what is wrong with code ?I have read many posts related to this but nothing is helping me .