SendEmptyPushNotification to gateway.push.apple.com no longer working

Me too man. Let’s figure this out together like Apex Legends.

I have submitted a TSI to Apple. They sent out an email on feb 10 saying:

On March 29, 2021, token and certificate-based HTTP/2 connections to the Apple Push Notification service must incorporate the new root certificate (AAACertificateServices 5/12/2020) which replaces the old GeoTrust Global CA root certificate. To ensure a seamless transition and to avoid push notification delivery failures, verify that both the old and new root certificates for the HTTP/2 interface are included in the Trust Store of each of your notification servers before March 29.

Note that Apple Push Notification service SSL provider certificates issued to you by Apple do not need be to updated at this time.

Learn more about connecting to APNs.

If you have any questions, contact us.

Best regards,
Apple Developer Relations

Update – Mon May 3, after submitting a TSI to Apple Dev

  1. Push notifications stopped working for developers on March 31, 2021 after Apple migrated to a new APNS provider API (http/2 protocol).

  2. To continue using push, see this page: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/

What I learned?

Revoke all developer account certificates related to APNS
Make new certs and this time don’t make any PEM files when installing them to your providing server. Also, make sure to stop using port 2195 when making a connection to APNS and use 443 or 2197.

The great news? The new APNS provider API is still compatible with Objective C!

🐆

<?php
// Put your device token here (without spaces):
$deviceToken = '09a0c8ff92b3621c5f5032c1fa031f2851d01dd99beaf1446c281c5458fe2ffd';
// 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://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 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);

Update: I was wrong about the PEM aspect. Creating a PEM file is still necessary for APNs connections using the new APNs Provider API.

Leave a Comment