Ph3nol / NotificationPusher

Standalone PHP library for easy devices notifications push.
MIT License
1.18k stars 274 forks source link

APNs provider API requirement starts March 31 #199

Open domenico-renna opened 3 years ago

domenico-renna commented 3 years ago

Last Friday Apple send to our company this mail message:

The HTTP/2‑based Apple Push Notification service (APNs) provider API lets you take advantage of great features, such as authentication with a JSON Web Token, improved error messaging, and per‑notification feedback. If you still send push notifications with the legacy binary protocol, make sure to upgrade to the APNs provider API as soon as possible. APNs will no longer support the legacy binary protocol after March 31, 2021.

We are using your great library to send android/ios push notification (version 2.3.1) can you confirm as that your library support the new apple specification?

If you don't support that specification in 2.3.1 or newer release of your library do you plan to support that in the next one?

seyfer commented 3 years ago

@Ph3nol ping

I have no time atm, unfortunately. Shall we mark the repository as not maintained in the Readme title?

domenico-renna commented 3 years ago

If you can't fix the APNs provider mark this repo as "not maintained" will be inevitable I suppose

tlacroix commented 3 years ago

I personally and temporarily switched to this library in the meantime, only for Apple's APNs: gepo/apns-http2.

It hasn't changed much in the past 4 years, but it works great, and the maintainer replies quickly to pull requests.

The doc is minimal, but I've sent a PR with improvements to the README.md file, it should be merged shortly.

Switching from ZendFramework's library to this one for Apple's APNs should be pretty simple. It took me about 2 hours to get it working alongside this one that I kept for FCM/GCM, and most of it was to go through new hoops (topic is mandatory, the new AAA certificate now is too since yesterday, etc.)

I don't have time to do it right now though, but the "complex" example in my documentation PR should cover pretty much everything except the unit tests.

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Apns\Client as ApnsClient;
use Apns\Message as ApnsMessage;
use ApnsException;

$token = 'a00915e74d60d71ba3fb80252a5e197b60f2e7743f61b4411c713e9aabd2854f';

// Check if token format is valid
if ((!ctype_xdigit($token)) || (64 != strlen($token))) {
   die('Token is invalid!');
}

// Create client with production certificate and passphrase
$client = new ApnsClient(
    [
        __DIR__ . '/certs/apns-prod-cert.pem',
        'my-passphrase'
    ], 
    false // false is for production, true for sandbox
);

// Get topic from certificate file
if ($cert = openssl_x509_parse(file_get_contents($apnsClient->getSslCert()[0]))) {
    $topic = $cert['subject']['UID'];
}

// Create message
$message = (new ApnsMessage())
    ->setDeviceIdentifier($token)
    ->setAlert('This is a test message sent on '.gmdate('r'))
    ->setData([
        'Key1' => 'Value1',
        'Key2' => 'Value2',
        'Key3' => 'Value3',
    ])
    ->setTopic($topic);

// Send it and catch errors
try {
    $client->send($message);
} catch (ApnsException $e) {
    // https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW17
    switch ($e->getMessage()) {
        case 'BadDeviceToken':
        case 'ExpiredProviderToken':
        case 'InvalidProviderToken':
        case 'MissingProviderToken':
        case 'Unregistered':
            // do something, ie. remove the token from your list
            break;
        case 'BadCollapseId':
        case 'BadExpirationDate':
        case 'BadMessageId':
        case 'BadPriority':
            // do something, ie. check your parameters
            break;
        case 'BadTopic':
        case 'MissingTopic':
        case 'DeviceTokenNotForTopic':
            // do something, ie. check that your topic is ok
            break;
        case 'BadCertificate':
            // do something, ie. check the certificate you provided
            break;
        case 'BadCertificateEnvironment':
            // do something, ie. check your certificate/environment (sandbox or production)
            break;
        case 'TooManyRequests':
        case 'TooManyProviderTokenUpdates':
            // do something, ie. throttle your requests
            break;
        default:
            // do something
            break;
    }
} 
sarveshamrit commented 3 years ago

@tlacroix sir can u tell how to replace ZendFramework's library to this one https://github.com/gepo/apns-http2 as ios notification are no longer being sent

tlacroix commented 3 years ago

@sarveshamrit See the example above: https://github.com/Ph3nol/NotificationPusher/issues/199#issuecomment-810416186

sarveshamrit commented 3 years ago

@sarveshamrit See the example above: #199 (comment)

Sir u said u did PR is not it approved somewhere, i am new i don't know how to replace it with zend because currently my push is dependent on laravel-push-notification which used NotificationPusher which finally uses zend apns library

ohdonpiano commented 3 years ago

Hi all, I made an HTTP/2 version of zendservice-apple-apns (fork here) and I used it as dependency on a NotificationPusher fork here

my main focus is on restoring ios push notifications basic functionality, while keeping NotificationPusher dependency.

I've replaced the old socket implementation in Zend lib with a Curl one that requires curl with http2 being installed

I've added an end-to-end test that works under php 5.6 and 7.4

I'm not an expert on releasing forks so let me know if something is missing. I'm going to use this library in production so I'm interested in keeping high standards

DanielAGW commented 3 years ago

@ohdonpiano Thank you so much! We just imported your fork into our environment and it works perfectly!

migliozziilaria commented 2 years ago

Hello @ohdonpiano,

I would like to adopt your fork but I'm running into problems.

It seems that the composer is loading the zendframework/ZendService_Apple_Apns library and not your fork.

In fact, when I try to instantiate the ApnsAdapter object by passing the bundleId parameter (the new parameter you added on August), the NotificationPusher/Adapter/Apns.php class throws an exception because the setBundleId method does not exist.

Can you please help me?

What I've done is just:

DanielAGW commented 2 years ago

@migliozziilaria Hi. What we did was:

  1. We forked 1:1 this repo https://github.com/ohdonpiano/ZendService_Apple_Apns to our own GitHub (just in case)
  2. We forked this repo https://github.com/ohdonpiano/NotificationPusher to our own GitHub (just in case) and updated its both composer.json and composer.lock by changing all occurrences of ohdonpiano/ZendService_Apple_Apns to the repo on our GitHub
  3. Made sure both libs are included in our app's composer.json, locked to specific versions (1.4.2 and 2.3.9) and that they are both referencing our GitHub repos (version lock might be overkill here)
  4. Updated our app's composer.lock to reflect the composer.json changes

It worked straight away.

ohdonpiano commented 2 years ago

You can otherwise avoid forking and declaring the composer dependencies like this: { "repositories": [ { "type": "github", "url": "https://github.com/ohdonpiano/ZendService_Apple_Apns" }, { "type": "github", "url": "https://github.com/ohdonpiano/NotificationPusher" } ], "require": { ... "sly/notification-pusher": "~2.3.8", ... } }