kukosk / pyapns_client

Simple, flexible and fast Apple Push Notifications on iOS, OSX and Safari using the HTTP/2 Push provider API.
Other
25 stars 11 forks source link

InvalidProviderToken in Django production mode. #2

Closed radetsky closed 3 years ago

radetsky commented 3 years ago

Hi, @kukosk
It is a strange issue. I made a Django application as a backend for a mobile app. When some event happens, like POST to URL, in handler I try to push iOS notification to my phone. The device token is registered and validated. When the Django app runs in development mode with python runserver command all fine. When I try to use gunicorn as production http server I got an error $subj. InvalidProviderToken. I tried to debug the issue, but only one difference was found. The JWT token is different. But it is normal because it different every time. PyJWT 2.1.0

When I try to use any python script with pyapns_client or Django app in development mode all things are OK. Under the gunicorn - failed. I sure if I will make a dedicated daemon/script all will be ok. But I do not want to dedicate the code.

Can you help me?

kukosk commented 3 years ago

Hi @radetsky,

The library is meant to be run as a daemon, which runs persistently in the background, not under gunicorn. So you should create a separate management task for it, and run it in a while loop (using systemd). The library is using persistent connection to APNS, and creates the JWT token which shouldn't change very frequently. I suppose the issue you're seeing is because in the way you implemented it, a new JWT token is generated for every push notification you want to send, which is not according to the Apple guidelines.

The way I do it is creating a separate database table for outgoing notifications, and then create just 1 instance of the client in a management task which runs indefinitely. After I have the client, I look for new notifications in the notifications table in a while loop (sleep between queries). That ensures you always only have 1 client, which is reusing the JWT token until it's valid, and then creates a new one only when it's needed.

Hope this helps :)

radetsky commented 3 years ago

Thank you very much for your explanation. It helps.