I have stored device tokens in a database, to which I send messages via PHP. No push notifications have been received by any of the devices for two days. When I send the push message, I get the number of characters sent back in PHP. The device token sent is also correct. Nevertheless, my message does not arrive.
The request to the Feedback server does not bring any faulty device tokens.
Could it be that Apple generally blocks the push notifications because, for example, some device tokens are no longer available because the app has been deleted from the device?
I received the following email from Apple Support. Here is an excerpt from it:
...... Based on your reports that your Push Notifications have stopped working without any changes on your end, we suspect this could be due to continued use of the legacy Binary Interface which was retired March 31st, 2021 (https://developer.apple.com/news/?id=c88acm2b).
This change requires you to migrate your push servers to use the HTTP/2 API. Any push servers still using the legacy interface will be unable to connect to APNs, resulting in Push Notifications not working.
More information about the HTTP/2 provider API can be found in these two WWDC sessions:
You can read more about the new APNs Provider API here: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/ ........
So I have now changed my PHP file and it works:
function sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token) {
//////////////////////////////////////////////
// @param $http2ch the curl connection
// @param $http2_server the Apple server url
// @param $apple_cert the path to the certificate
// @param $app_bundle_id the app bundle id
// @param $message the payload to send (JSON)
// @param $token the token of the device
// @return mixed the status code
///////////////////////////////////////////////
// url (endpoint)
$url = "{$http2_server}/3/device/{$token}";
// certificate
$cert = realpath($apple_cert);
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
"User-Agent: My Sender"
);
// other curl options
curl_setopt_array($http2ch, array(
CURLOPT_URL => $url,
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLCERT => $cert,
CURLOPT_HEADER => 1
));
// go...
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($http2ch));
}
// get response
$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
return $status;
}
So you can call it:
include_once './sendHTTP2Push.php';
error_reporting(E_ALL);
// open connection
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// send push
$apple_cert = 'pem4.pem';
$message = '{"aps":{"alert":"Hi!","sound":"default"}}';
$token = 'c4942de20b30792b8f1e04c2f5488e05a24bf72f14f1fc849e6581faf9571111';
$http2_server = 'https://api.development.push.apple.com'; // or 'api.push.apple.com' if production
$app_bundle_id = 'com.gl.xxxxxxxx';
$status = sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token);
echo "Response from apple -> {$status}\n";
// close connection
curl_close($http2ch);
it works fine.
Create the key file pem4.pem
Create a push certificate on the Apple site under Certificates and download it ---> aps-XX.cer
Call up keychain management
Insert the downloaded file
Apple Push Service: Export Com.gl.xxxxxxxx ---> xxx.p12
Call the terminal program
cd desktop
openssl pkcs12 -clcerts -nodes -out pem4.pem -in xxx.p12
Copy pem4.pem to the server
this is now @param $ apple_cert (see below)