djacobs / PyAPNs

Python library for interacting with the Apple Push Notification service (APNs)
http://pypi.python.org/pypi/apns/
MIT License
1.22k stars 374 forks source link

Push not being recieved by devices anymore #111

Closed gregorskii closed 9 years ago

gregorskii commented 9 years ago

Hi there,

We are using this plugin on Google App Engine with a Cloud Endpoints project.

Several months back when we were testing the integration the push messages were sending.

We have not made any major modifications to our push code and now the messages are not sending.

The App Engine logs show:

GatewayConnection APNS connection establishing...
GatewayConnection APNS connection established
GatewayConnection APNS connection closed

and does not report any 500 errors or SSL/key errors. But the message is not received by the phone.

We are also getting "Deadline Exceeded Errors" at least one of the times we tried.

Our keys are signed correctly using this process:

in keychain access, select both cert and key then export to Certificates.p12 file.

to generate cert.pem openssl pkcs12 -in Certificates.p12 -out cert.pem -nodes -nokeys

to generate key.pem openssl pkcs12 -in Certificates.p12 -out key.pem -nodes -nocerts

Our push code is copied directly from the instructions:


def send_single_push(u, payload):

    apns = get_apns_handler(False)

    # Send multiple notifications in a single transmission
    frame = Frame()
    identifier = 1
    expiry = time.time()+3600
    priority = 10

    pa = PushAlias.query(PushAlias.user == u.key).fetch(1)

    if pa:
        pa = pa[0]

    bc = PushBadgeCount.query(PushBadgeCount.alias == pa.key).fetch(1)

    if bc:
        bc = bc[0]

    # Increase the badge count
    bc.badge_count += 1
    bc.put()

    # Set the payload data and badge count
    apns_payload = Payload(
        alert=payload['alert'],
        sound=payload['sound'] if payload.has_key('sound') and payload['sound'] else "default",
        badge=bc.badge_count
    )

    # Add a push to the frame for each device in the alias
    for device in pa.devices:
        frame.add_item(device, apns_payload, identifier, expiry, priority)

    if get_environment() != 'sandbox':
        try:
            apns.gateway_server.send_notification_multiple(frame)
        except:
            # Force re-connect
            apns.gateway_server._connect()

        return False, None

We are mimicking Urban Airship like functionality.

And the keys are set as such:


def get_apns_handler(enhanced=False):

    sandbox = True
    cert = APNS_CERT_SANDBOX
    pem = APNS_PEM_SANDBOX

    # if get_environment() == 'prod':
    #     sandbox = False
    #     cert = APNS_CERT_PRODUCTION
    #     pem = APNS_PEM_PRODUCTION

    return APNs(use_sandbox=sandbox, cert_file=cert, key_file=pem, enhanced=enhanced)

We are using Googles own SSL library via the app.yaml:


libraries:
    - name: ssl
      version: latest

Any help would be greatly appreciated. Let me know if you need more information.

CTassisF commented 9 years ago

Hey,

I'm currently using PyAPNs in a GAE project and I am not seeing any errors.

A few advices:

If you're still seeing problems check if you're not sending messages to sandboxed tokens without "use_sandbox = True" (or vice versa).

gregorskii commented 9 years ago

Thanks @CTassisF

We are loading the certificates like this and it worked previously:


##
# APNS
##

APNS_CERT_SANDBOX = os.path.join(os.path.dirname(__file__), 'apns_keys/development_cert.pem')
APNS_PEM_SANDBOX = os.path.join(os.path.dirname(__file__), 'apns_keys/development_key.pem')
APNS_CERT_PRODUCTION = os.path.join(os.path.dirname(__file__), 'apns_keys/production_key.pem')
APNS_PEM_PRODUCTION = os.path.join(os.path.dirname(__file__), 'apns_keys/production_key.pem')

And we are not getting any SSL errors with the certs.

CTassisF commented 9 years ago

@gregorskii I had a few problems loading certificates from files when I started using PyAPNs on GAE and that's why I'm using StringIO.StringIO(). I'm also not using the latest PyAPNs version available (v2.0.1), I'm using v2.0 because of #108. This is the log when my push'es are sent:

D 2015-02-20 19:23:40.333 GatewayConnection APNS connection establishing... D 2015-02-20 19:23:40.618 GatewayConnection APNS connection established I 2015-02-20 19:23:40.627 GatewayConnection APNS connection closed

Your log matches mine. I can't think anything but wrong token/sandbox combinations or problems with certificate loading.

gregorskii commented 9 years ago

I believe I am using the most current version, however the files do not denote the version anywhere that I can see.

I am pulling from https://github.com/djacobs/PyAPNs.git I do not remember specifically the last time I reran pip install -r from my requirements file. But I believe it was recently. I can try that again.

If the certificate did not load wouldn't the call to APNS throw a SSL connection error? When we were messing with the certs last night and had it setup wrong it was indeed throwing an error which resulted in a 500 error to our front end.

I will try rebuilding my package requirements, but its good that someone else is using this plugin on App Engine and having success, we must just have a config issue somewhere.

If you or anyone else has any other suggestions we would greatly appreciate it.

Thanks!

gregorskii commented 9 years ago

I tried updating the modules via pip install -r from my requirements file. I also tried using StringIO.StringIO to read the cert files. Neither worked.

I am still at a loss for how to fix this.

Does anyone know of any other debugging techniques to get more detail into what is happening?

Thanks

FredrikL commented 9 years ago

If it helps I had the same problem, turned out my cert file was wrong.

gregorskii commented 9 years ago

Would you mind adding the instructions you used to create the key and load it in app engine? The ones I used are above.

I would really appreciate it.

gregorskii commented 9 years ago

I changed enhanced mode to True and the pushes started sending. Can anyone explain why enhanced False and enhanced True would cause this to happen?

gregorskii commented 9 years ago

Resolved by using enhanced=True