APNS push notifications not being sent - php

Actually I am new to APNS and I have been using some help from the online forums and blogs. I am using PHP to implement the server side. The following is my PHP code
<?php
// Put your device token here (without spaces):
$deviceToken = '0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// 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'
);
// 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 '
' . PHP_EOL;
// Close the connection to the server
fclose($fp);
I have converted the .p12 file to a PEM file and named it as ck.pem and has hosted it on the same location as the php file resides. When I execute the PHP file, the following gets printed. Is there something I am missing. I am doubtful about the certificate part.
Connected to APNS
Message successfully delivered

I had the exact same problem, using the exact same example code - works perfect for android but fails for IOS with no returning error.
To fix my problem I had to create the SSL cert again against the app and then run
openssl x509 -in aps_development.cer -inform der -out aps_development.pem
openssl pkcs12 -nocerts -out aps_developmentKey.pem -in ios_development.p12
cat aps_development.pem aps_developmentKey.pem > ck.pem
Finially tested against:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert aps_development.pem -key aps_developmentKey.pem -CAfile entrust_2048_ca.cer
After this everything worked perfect, that was on the 29th Sept - Its now stopped working so I think its the Certs again but at least it may help you with your solution.

I actually replaced the UDID of the device with the Device Token and it works like a charm. You cannot use UDID anymore.

Related

Error when try to excute Apple Push Notification through php file

I'm working on push notification in IOS with php server and I produced the certificate and keys of the app also I'm ensure from unblocking port for ssl://gateway.sandbox.push.apple.com:2196 and 2195 but at all time I get this error during try to connect on ssl also I'm sure from the permission of all key files
Warning: stream_socket_client(): SSL: crypto enabling timeout in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Warning: stream_socket_client(): Failed to enable crypto in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Failed to connect: 0
Edited:
When I'm trying this command
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCertificate.pem -key PushKey.pem -CApath /etc/ssl/certs/Entrust_Root_Certification_Authority.pem
I get this error
CONNECTED(00000003)
write:errno=54
php file:
<?php
// Put your device token here (without spaces):
$deviceToken = 'mydevicetokenhere';
// Put your private key's passphrase here:
$passphrase = '1234';
$message = $argv[1];
$url = $argv[2];
if (!$message || !$url)
exit('Example Usage: $php newspush.php \'Breaking News!\' \'https://raywenderlich.com\'' . "\n");
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.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',
'link_url' => $url,
);
// 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 searched a lot about this issue and I tried all possible solutions but without any result what I can do now ?
Edited:
After add -debug to openssl command the most strange thing these lines:
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.pem');
This line looks like you are using production certificate to connect to sandbox APNS. Try using development certificate. You can get the same from apple developer dashboard.

Forbidden access when connecting to Apple Push Notification service

I have some troubleshooting when trying to push a notification to my iPhone using the APNs. I use a PHP code that I keep seeing over and over on the Internet so I don't think the problem is about it:
<?php
// Put your device token here (without spaces):
$deviceToken = 'mytoken'; // Of course this is my correct token here
// Put your private key's passphrase here:
$passphrase = 'mypassphrase'; // Same here
$message = $argv[1];
$url = $argv[2];
if (!$message || !$url)
exit('Example Usage: $php newspush.php \'Breaking News!\' \'https://raywenderlich.com\'' . "\n");
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', __DIR__.'/cert.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'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',
'link_url' => $url,
);
// 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;
stream_set_blocking($fp, 0);
// 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 have the output "Message successfully delivered", so the connection has been successfully established, idem for the sent message. However, the device does not receive anything.
I used the feedback feature to try to know what's wrong, but the result is empty (the array is literally empty):
<?php
function send_feedback_request() {
//connect to the APNS feedback servers
//make sure you're using the right dev/production server & cert combo!
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', __DIR__.'/cert3.pem');
stream_context_set_option($stream_context, 'ssl', 'passphrase', 'meteor0405');
$apns = stream_socket_client('ssl://feedback.sandbox.push.apple.com:2196', $errcode, $errstr, 60, STREAM_CLIENT_CONNECT, $stream_context);
if(!$apns) {
echo "ERROR $errcode: $errstr\n";
return;
}
$feedback_tokens = array();
//and read the data on the connection:
while(!feof($apns)) {
$data = fread($apns, 38);
if(strlen($data)) {
$feedback_tokens[] = unpack("N1timestamp/n1length/H*devtoken", $data);
}
}
fclose($apns);
return $feedback_tokens;
}
var_dump(send_feedback_request());
Would you have any idea on what I can do to figure out what's wrong? Can it be due to the certificate? A .cer file has been generated from the Apple website and been imported into Keychain Access to make a .p12 file. Then, I converted it to .pem format thanks to an openssl command, and this is the one I use in files below.
Thank you!
If you are getting the successful message then it means your PHP code is correct but something is missing from the pem file.Checkout the pem file creation steps here https://www.digicert.com/ssl-support/pem-ssl-creation.htm and try it again.Hope it will help.
The problem was indeed coming from my PEM file. To anyone having the same issue, here is what I did.
After having downloaded the certificate and private key from the iPhone Developper Connection Portal in the .p12 format, I had to convert them into .pem format. After that, I had to merge the two files (put the content of the certificate first, then the private key). This merge has to be put in a new .pem file, and this is the file to use in the PHP script.
Here is the full tutorial I followed: https://blog.serverdensity.com/how-to-build-an-apple-push-notification-provider-server-tutorial/
Moreover, the PHP code is not exactly the same. The one I used in the first post was not correct, use the tutorial's one instead.

Update Passbook wallet failed to connect

i'm struck with update wallet push notiifcation,i used bellow code,server not connected error.
I missed any credentials.please help to me ,fix this issue.
I registered my passbook and get back pushtoken to server.
this key same as the passbook generate certificate key.
$certifile = 'passbook/certificates/AppleWWDRCA.pem';
$passphrase = 'xxxxxxxx';
$trust ='';
$url = 'ssl://gateway.push.apple.com:2195';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $certifile);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client($url, $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;
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'pushToken'=>'xxxxxxxxxxxxxx',
'passTypeId'=>'xxxxxxxxx'
);
$payload = json_encode($body);
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
// Close the connection to the server
fclose($fp);
Please help to me.
Connected to server.but i have error in sending push notifictaion.
$body['aps'] = array( );
$msg = chr(0) . pack('n', 32) . pack('H*', $pushToken) . pack('n', strlen($payload)) . $payload;
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
Message not delivered: 10053.
user booking time dynamically pass created and display to device.
if user modify the booking date .I need to update dynamically booking date and time to user pass via pushnotification.
any one please help to me update my passbook.
check here for PHP code (first answer). It's work for me.
PHP Apple Enhanced Push Notification read error response
You use the wrong certification. You have to make pem file from your pass certification (p12) by export from keychain.
How to make P12 and PEM file from cer file
1. move into save folder
2. open terminal and cd to that folder
openssl x509 -inform der -in aps_development.cer -out certificate.pem
openssl pkcs12 -nocerts -in Certiticates.p12 -out p12Certificates.pem
[type password for .p12 and password for .pem]
cat certificate.pem p12Certificates.pem > apns_cert.pem

Push Notification Crypto error

I use Push Notifs in my PHP Laravel app. I created a pem file and tested it. When using it on my dev machine, it correctly pushes to the mobile device. When I now push the whole project to my production server, and start the pushnotif call, I get the error: Failed to enable crypto
Do I need to create a special pem file while being on production server? And I am not talking about "production certificates" I still want to use the sandbox for testing
<?php
namespace App\Helpers;
use Carbon\Carbon;
use Illuminate\Support\Facades\Config;
class PushNotificationHelper {
public function pushToResponder($deviceToken) {
// Set device token of mobile device and the passphrase for certification
$pushToken = $deviceToken;
$passphrase = Config::get('MFConfig.PushNotificationTest.passPhrase');
$APNS = Config::get('MFConfig.PushNotificationTest.APNS');
// Open new context for streaming and set certificate as well as passphrase
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '../App/Certificates/ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
stream_context_set_option($ctx, 'ssl', 'cafile', '../App/Certificates/entrust_2048_ca.cer');
// Open connection to APNS
$fp = stream_socket_client($APNS, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
// If no connection could be made then fail with error, otherwise connect
if (!$fp) {
exit("Failed to connect: $err, $errstr" . PHP_EOL);
}
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => "MEDIFAKTOR Einsatz",
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $pushToken) . pack('n', strlen($payload)) . $payload;
// Send to server
$result = fwrite($fp, $msg, strlen($msg));
// If no result is available, the message was not delivered.
if(!$result) {
echo 'Message not delivered.' . PHP_EOL;
} else {
echo 'Message successfully delivered.' . PHP_EOL;
}
// Close connection
fclose($fp);
}
}
I tested the connection with:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert ck.pem -debug -showcerts -CAfile entrust_2048_ca.cer
and it returns status 0 (ok) which is fine I think?
but when I call the function I get: failed loading cafile stream
Not sure about this, but it might be your php settings in the dev enviroment.
try to locate the cacert.pem file.
If you are using a linux system you can try locate cacert.pem using the terminal.
When you find the location find the php.ini file and find this line:
;openssl.cafile =
and change this to
openssl.cafile= path from locate cacert.pem command or the location the .pem is actually located.
Report back on how it went.

Apple Push Notification SSL Error

I got the following error message, when trying to send a push notif via PHP:
stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
I guess it could be the issue with the SSL3 problems in the past? But does this mean the script is not usable that way anymore? What do I need to change, as i have no clue. I checked all certificates and they are working. I can connect to the sandbox at apple via terminal with the certificates and the handshake seems to work via terminal.
This is my PHP Script
class PushNotification {
public function sendTestMessageToDevice($message){
$devicetoken = Config::get('mfsconfig.PushNotificationTest.deviceToken');
$passphrase = Config::get('mfsconfig.PushNotificationTest.passPhrase');
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open connection to APNS
$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 a binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $devicetoken) . pack('n', strlen($payload)) . $payload;
// Send to server
$result = fwrite($fp, $msg, strlen($msg));
if(!result) {
echo 'Message not delivered' . PHP_EOL;
} else {
echo 'Message successfully delivered' . PHP_EOL;
}
fclose($fp);
}
I think I got the solution:
Click the disclosure arrow next to your certificate in Keychain Access and select the certificate and the key.
Right click and choose Export 2 items
Choose the p12 format from the drop down and name it cert.p12.
Now covert the p12 file to a pem file:
$ openssl pkcs12 -in cert.p12 -out apple_push_notification_production.pem -nodes -clcerts
After uploading the newly created pem file, everything works smoothly!

Categories