phpioscurlapple-push-notificationsapns-php

Apple Push Notifications with p8 file working on my Mac, but doesn't work on Linux server


I'm trying to switch the APNS for my apps from p12 over to the new p8 format. It works fine on my Mac and sends notifications with no problems. However, when I setup the same config on my Amazon Linux servers, I get nothing. I'm having a rough time figuring out what is different. This is the function I am using. It works fine when run on my local host, but not on the remote servers. Also, note that the $result from curl_exec($http2ch) is coming back as false for the remote servers.

public function sendNotification($token, $message, $badge, $env){
    $keyfile = 'AuthKey_mykey.p8';                
    $keyid = 'my key id';                        
    $teamid = 'my team id';                       
    $bundleid = 'org.tciweb.y2go';                

    if ($env == 'dev') {
        $url = 'https://api.development.push.apple.com';
    } else {
        $url = 'https://api.push.apple.com';
    }

    $payload = '{"aps":{"alert":"'.$message.'","sound":"default"}}';

    $key = openssl_pkey_get_private('file://'.$keyfile);

    $header = ['alg'=>'ES256','kid'=>$keyid];
    $claims = ['iss'=>$teamid,'iat'=>time()];

    $header_encoded = $this->base64($header);
    $claims_encoded = $this->base64($claims);

    $signature = '';
    openssl_sign($header_encoded . '.' . $claims_encoded, $signature, $key, 'sha256');
    $jwt = $header_encoded . '.' . $claims_encoded . '.' . base64_encode($signature);

    // only needed for PHP prior to 5.5.24
    if (!defined('CURL_HTTP_VERSION_2_0')) {
        define('CURL_HTTP_VERSION_2_0', 3);
    }

    $http2ch = curl_init();
    curl_setopt_array($http2ch, array(
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
        CURLOPT_URL => "$url/3/device/$token",
        CURLOPT_PORT => 443,
        CURLOPT_HTTPHEADER => array(
            "apns-topic: {$bundleid}",
            "authorization: bearer $jwt"
        ),
        CURLOPT_POST => TRUE,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HEADER => 1
    ));

    $result = curl_exec($http2ch);
    if ($result === FALSE) {
        // error handling
    }

    $status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
    echo $status;
    return 0;
}

I checked the curl versions... 7.64.1 on my local machine and 7.61.1 on the servers. I also ran "Push Notifications Tester" to verify that the keys and device token work.

I've done a bunch of searching, but am getting really confused. Could this be something to do with HTTP2? Is there an alternative to using CURL? Any suggestions appreciated.


Solution

  • Upgrading PHP to version 7.3 solved the problem. I was originally on version 7.0.