I am using PHP to try to send a push notification to my iOS app. My push code looks like this:
<?php
$title="Notification";
$message=array();
$message['text']="Message";
$message['id']=1;
$to='695D55573361DB9948D09AB43EA1548A9AAECB4D23F7D836BD7F88FA94ABBE5E';
echo $to.PHP_EOL;
sendPushAPN($to,$title,$message);
function sendPushAPN($to,$title,$message)
{
$to=str_replace(" ","",$to);
// Put your device token here (without spaces):
$deviceToken=$to;
// Put your private key's passphrase here:
$passphrase = 'abc';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'aps.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
// codi existent //$body['aps'] = array('alert' => "ole.. alex",'sound'=> 'default','push_type' => 'alert');
$body['aps']=array('alert' => array('title' => 'Notificacion','body' => 'Ok Alex'),'sound' => 'default');
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// $msg = pack("C", 1) . pack("N","alert") . pack("N",$deviceToken) . pack("N", $apple_expiry) . pack("n", 32) . pack('H*', str_replace(' ', '', $deviceToken'])) . pack("n", strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
// Close the connection to the server
fclose($fp);
echo 'Result:' . $result . PHP_EOL;
}
?>
But my output always looks the same:
Connected to APNS
Result:114
and the push notification never arrives. What does 114 code mean? Is there any way to get more information about what is going on? Or perhaps I'm just using a wrong way of sending push notifications?
Your code is using the legacy binary API for APNS.
This is no longer supported.
You need to use the HTTP/2 API.
A quick web search seems to indicate that there are a few different PHP libraries that can provide this as well as sample code.
Related
I am trying to migrate an existing API that used APNs to send and receive messages to be compatible with the new APNs Provider API.
The following script worked for sending test notifications to my testing device before Apple stopped supporting the legacy binary protocol.
//simplepush.php
<?php
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
////////////////////////////////////////////////////////////////////////////////
$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://api.sandbox.push.apple.com:443', $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);
Sending Notification Requests to APNs states that the :method and :path header fields are required for a connection to APNs.
I've copied the code from the link to the original test script.
<?php
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/EXAMPLETOKEN
host = api.sandbox.push.apple.com
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
apns-push-type = alert
apns-expiration = 0
apns-priority = 10
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN'; // Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
///////////////////////////////////////////////////////////////////. /////////////
$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://api.sandbox.push.apple.com:443', $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);
When I try to run the script, the terminal output is:
PHP Parse error: syntax error, unexpected token ":" in /Users/Desktop/simple push folder/simplepush.php on line 6
What is the correct way to add the newly required header fields to this script?
Note: I've used the following Apple documentation to send a test notification to my testing advice.
PHP said that your file have a syntax error. I believe it has nothing to do with request header.
I try to send multiple notifications with one hit. Many users have more than one device and i put their device tokens into an array. It is working fine but if there is a wrong token Apple is disconnecting me and the device with working token gets no push notification. I've read about a error-response-solution at this post: Apple Push Notification Limits
But this solution is not working for me. It says: Status:7-Invalid payload size.
But there is only the message "test" and I'm sure the reason is the wrong token. How could I continue the foreach script without disconnecting?
// Put your device token here (without spaces):
$deviceToken = array('WRONG_TOKEN', 'WORKING_TOKEN');
// Put your private key's passphrase here:
$passphrase = 'PASS';
// Put your alert message here:
$message = "test";
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'cer.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' => "www/sound.mp3",
'content-available' => 1,
'badge' => 1
);
// Encode the payload as JSON
$payload = json_encode($body);
//foreach für array
foreach($deviceToken as $token){
$msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
}//foreach end
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
//checkAppleErrorResponse($fp);
// Close the connection to the server
fclose($fp);
I am using following code to send push notification to ios devices. I am getting successfully delivered message in php side but not receiving push in iOS device.
I have checked with replacing .pem files nd also tested with sendbox and production both. Its not working both. Please provide me the way of debugging this issue.
function iosTest($tToken)
{
// Provide the Host Information.
//$tHost = 'gateway.sandbox.push.apple.com';
$tHost = 'gateway.push.apple.com';
$tPort = 2195;
//echo "hi";
// Provide the Certificate and Key Data.
$tCert = $_SERVER['DOCUMENT_ROOT'].'/N****d.pem';
// Provide the Private Key Passphrase (alternatively you can keep this secrete
// and enter the key manually on the terminal -> remove relevant line from code).
// Replace XXXXX with your Passphrase
$tPassphrase = 'harsh';
// Provide the Device Identifier (Ensure that the Identifier does not have spaces in it).
// The message that is to appear on the dialog.
$tAlert = 'Testing..';
// The Badge Number for the Application Icon (integer >=0).
$tBadge = 1;
// Audible Notification Option.
$tSound = 'default';
// The content that is returned by the LiveCode "pushNotificationReceived" message.
$tPayload = 'APNS Message Handled by LiveCode';
// Create the message content that is to be sent to the device.
$tBody['aps'] = array (
'alert' => $tAlert,
'badge' => $tBadge,
'sound' => $tSound,
);
//$tBody ['payload'] = $tPayload;
// Encode the body to JSON.
$tBody = json_encode ($tBody);
echo $tBody;
// Create the Socket Stream.
$tContext = stream_context_create ();
stream_context_set_option ($tContext, 'ssl', 'local_cert', $tCert);
// Remove this line if you would like to enter the Private Key Passphrase manually.
stream_context_set_option ($tContext, 'ssl', 'passphrase', $tPassphrase);
// Open the Connection to the APNS Server.
$tSocket = stream_socket_client ('ssl://'.$tHost.':'.$tPort, $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $tContext);
// Check if we were able to open a socket.
if (!$tSocket)
exit ("APNS Connection Failed: $error $errstr" . PHP_EOL);
// Build the Binary Notification.
$tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;
// Send the Notification to the Server.
$tResult = fwrite ($tSocket, $tMsg, strlen ($tMsg));
if ($tResult)
echo 'Delivered Message to APNS' . PHP_EOL;
else
echo 'Could not Deliver Message to APNS' . PHP_EOL;
// Close the Connection to the Server.
fclose ($tSocket);
//send_feedback_request();
}
Thanks in advance.
Kindly use the following code as it working on my end
<?php
// Put your device token here (without spaces):
$deviceToken = '17b2f31afd5c9736ad48ffca8d1936046431c6fc1f3f3ac661bcbfbf97ca60cc';
// Put your private key's passphrase here:
$passphrase = '';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'HireRightNew.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' => 'Breaking News',
'sound' => 'default',
'link_url' => $url,
'category' => 'NEWS_CATEGORY',
);
// 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);
?>
I am trying to implement push notification in iOS in PHP using APNS library. Here is my code :
<?php
// Put your device token here (without spaces):
$deviceToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
// Put your private key's passphrase here:
$passphrase = 'XXXXXX';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'Certificates.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'
);
// 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));print_r($result);
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
?>
It show message sending successfully but in iOS it does not show notification.
2015-07-28 08:32:39 Connected to APNS result = 97
2015-07-28 08:32:39 Message successfully delivered
2015-07-28 08:32:39 Connection closed to APNS
Why this is happening? Am I missing anything ?
his mistake is with the ios 9 if so stop using the code in objective C and use in swift as it has a bug in generating objectiv token - C for ios9.
I recommend urgent change your code.
Also through this thought was the server when the scheduled ios changed for swift everything was resolved and my php was almost equal.
Care:
$ msg = chr (0). pack ('N', 32). pack (H * ','. '$deviceToken [0].'). pack ('N', strlen ($ payload)). $ payload;
There are two potential reason that is causing this:
Your app is in foreground
Your device token is invalid
In my app. I am directly getting deviceToken that's in NSData
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *deviceTokenString = [NSString stringWithFormat:#"%#", deviceToken];
// this is producing something like:
// <xxxxxxx 9b0f527f xxxxxxxx 2727ed28 xxxxxxxx 4e693a61 xxxxxxx ac2f7dbb>
//
// and i am directly saving that to my servers database
Here's what i have in my server.
$from_database = "<xxxxxxx 9b0f527f xxxxxxxx 2727ed28 xxxxxxxx 4e693a61 xxxxxxx ac2f7dbb>";
// this removes the '<' and '>' to make the device token valid
//
$token_string = substr($from_database, 1, -1);
$token_array[] = $token_string;
// you can also add multiple 'token_string' to the 'token_array' for push notification broadcasting, i am currently doing that and it is working properly.
...
public function __push_notification($message_input, $token_array)
{
$message = stripslashes($message_input);
$passphrase = 'xxxxxx';
$cert = realpath('xxx.pem');
$payload = '{
"aps" :
{
"alert" : "'.$message.'",
"badge" : 1,
"sound" : "bingbong.aiff"
}
}';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $cert);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
{
// echo "Failed to connect $err $errstr <br>";
return;
}
else
// echo "Post notification sent<br>";
$dev_array = array();
$dev_array = $token_array;
foreach ($dev_array as $device_token)
{
$msg = chr(0) .
pack("n", 32) .
pack('H*', str_replace(' ', '', $device_token)) .
pack("n", strlen($payload)) .
$payload;
// echo "sending message :" . $payload . "n";
fwrite($fp, $msg);
}
fclose($fp);
}
Also check this, might be helpful: Facing problems in ios push notification php code
I have the following php code for ios push notification.Here i code for 2 devices using loop in fwrite() section . the current code is working properly . My doubt is , can i pass the array of device tokens directly without using the for loop?.
<?php
// Put your device token here (without spaces):
$deviceToken[0] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$deviceToken[1] = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';
// Put your private key's passphrase here:
$passphrase = '123456';
// Put your alert message here:
$message = 'multiple device push notification...!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'abc.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',
'badge' => '+1'
);
// Encode the payload as JSON
$payload = json_encode($body);
for($i=0;$i<2;$i++)
{
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken[$i]) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
echo "msg may be delivered";
}
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Its design by default, yet there is no option for passing array of device tokens. You have to iterate through the loop.
Alternate to this approach will be using third party like amazon SNS service. Here you can publish to topic(one request) and all devices that are subscribed to this topic will receive the notification.