[GH-ISSUE #692] support iOS 16.4 web push #510

Closed
opened 2026-05-07 00:24:55 +02:00 by BreizhHardware · 9 comments

Originally created by @helmut72 on GitHub (Apr 1, 2023).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/692

💡 Idea support iOS 16.4 web push. Then there is no native App needed. Thank you.

Edit: It also solve this in your FAQ:
"The iOS is very bare bones and quite frankly a little buggy. I wanted to get something out the door to make the iOS users happy, but halfway through I got frustrated with iOS development and paused development."

Originally created by @helmut72 on GitHub (Apr 1, 2023). Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/692 :bulb: **Idea** support iOS 16.4 web push. Then there is no native App needed. Thank you. Edit: It also solve this in your FAQ: "The iOS is very bare bones and quite frankly a little buggy. I wanted to get something out the door to make the iOS users happy, but halfway through I got frustrated with iOS development and paused development."
BreizhHardware 2026-05-07 00:24:55 +02:00
Author
Owner

@Mikaela commented on GitHub (Apr 2, 2023):

I think this is practically #346 as that is what iOS 16.4 requires for push notifications

<!-- gh-comment-id:1493301960 --> @Mikaela commented on GitHub (Apr 2, 2023): I think this is practically #346 as that is what iOS 16.4 requires for push notifications
Author
Owner

@helmut72 commented on GitHub (Apr 2, 2023):

Yes

<!-- gh-comment-id:1493312017 --> @helmut72 commented on GitHub (Apr 2, 2023): Yes
Author
Owner

@binwiederhier commented on GitHub (Jun 27, 2023):

📢 Request for testing:

The next ntfy server release will contain a progressive web app (PWA) with Web Push support, which means you'll be able to install the ntfy web app on your desktop or phone similar to a native app (even iOS! 🥳), and get basic push notification support (without any battery drain).

Installing the PWA gives ntfy web its own launcher (e.g. shortcut on Windows, app on macOS, launcher shortcut on Linux, home screen icon on iOS, and launcher icon on Android), a standalone window, push notifications, and an app badge with the unread notification count.

The (hopefully) production ready version of the PWA is currently deployed on https://staging.ntfy.sh/app -- Install instructions with screenshots can be found in the docs (https://docs.ntfy.sh/subscribe/pwa/).

Please report bugs or issues on Discord/Matrix/Lemmy. PLEASE HELP TEST

Huuuuge thanks goes to @nimbleghost for developing this entire feature top to bottom. If you throw donations my way, I'll share them with him. He certainly deserves it for all this great work. 👏

<!-- gh-comment-id:1608600906 --> @binwiederhier commented on GitHub (Jun 27, 2023): :loudspeaker: **Request for testing:** The next ntfy server release will contain a **progressive web app (PWA) with Web Push support**, which means you'll be able to **install the ntfy web app on your desktop or phone** similar to a native app (__even iOS!__ :partying_face:), and get basic push notification support (without any battery drain). Installing the PWA gives ntfy web its own launcher (e.g. shortcut on Windows, app on macOS, launcher shortcut on Linux, home screen icon on iOS, and launcher icon on Android), a standalone window, push notifications, and an app badge with the unread notification count. The (hopefully) production ready version of the PWA is currently deployed on https://staging.ntfy.sh/app -- Install instructions with screenshots can be found in the docs (https://docs.ntfy.sh/subscribe/pwa/). Please report bugs or issues on Discord/Matrix/Lemmy. **PLEASE HELP TEST** Huuuuge thanks goes to @nimbleghost for developing this entire feature top to bottom. If you throw donations my way, I'll share them with him. He certainly deserves it for all this great work. :clap:
Author
Owner

@binwiederhier commented on GitHub (Jul 1, 2023):

@gedw99 Thanks for the feedback! It's live now so you can test there too. It's a process :D

<!-- gh-comment-id:1615359966 --> @binwiederhier commented on GitHub (Jul 1, 2023): @gedw99 Thanks for the feedback! It's live now so you can test there too. It's a process :D
Author
Owner

@helmut72 commented on GitHub (Jul 1, 2023):

I also want to say thanks and it works most of the time. I don't use it for anything right now, just fire a curl command for testing to get a feeling how reliable it is. A very few time the first curl command will be ignored.

<!-- gh-comment-id:1615884331 --> @helmut72 commented on GitHub (Jul 1, 2023): I also want to say thanks and it works most of the time. I don't use it for anything right now, just fire a curl command for testing to get a feeling how reliable it is. A very few time the first curl command will be ignored.
Author
Owner

@nimbleghost commented on GitHub (Jul 1, 2023):

I also want to say thanks and it works most of the time. I don't use it for anything right now, just fire a curl command for testing to get a feeling how reliable it is. A very few time the first curl command will be ignored.

Do you see anything in the server logs when that happens?

<!-- gh-comment-id:1615917872 --> @nimbleghost commented on GitHub (Jul 1, 2023): > I also want to say thanks and it works most of the time. I don't use it for anything right now, just fire a curl command for testing to get a feeling how reliable it is. A very few time the first curl command will be ignored. Do you see anything in the server logs when that happens?
Author
Owner

@helmut72 commented on GitHub (Jul 1, 2023):

This is the log when both iPhones doesn't receive anything. Some IDs and IP are redacted:

2023/07/01 17:18:34 DEBUG Rate limiters reset for visitor (visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=0, visitor_messages_limit=17280, visitor_messages_remaining=17280, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=60, visitor_seen=2023-07-01T17:18:34.739Z)
2023/07/01 17:18:34 DEBUG HTTP request started (http_method=POST, http_path=/testtopic, tag=http, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=0, visitor_messages_limit=17280, visitor_messages_remaining=17280, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=60, visitor_seen=2023-07-01T17:18:34.742Z)
2023/07/01 17:18:34 DEBUG Received message (http_method=POST, http_path=/testtopic, message_body_size=38, message_call=, message_delayed=false, message_email=, message_event=message, message_firebase=true, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_unifiedpush=false, message_user=u_uuu, tag=publish, topic=testtopic, topic_last_access=2023-07-01T17:18:03.578Z, topic_subscribers=0, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.000344566, visitor_seen=2023-07-01T17:18:34.742Z)
2023/07/01 17:18:34 DEBUG Adding message to cache (http_method=POST, http_path=/testtopic, message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=publish, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0004209716, visitor_seen=2023-07-01T17:18:34.742Z)
2023/07/01 17:18:34 DEBUG Publishing web push message to 3 subscribers (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0006140932, visitor_seen=2023-07-01T17:18:34.742Z)
2023/07/01 17:18:34 DEBUG Wrote 1 message(s) in 1.438762ms (tag=message_cache)
2023/07/01 17:18:34 DEBUG Sending web push message (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0007800004, visitor_seen=2023-07-01T17:18:34.742Z, web_push_subscription_endpoint=https://web.push.apple.com/long-id-1, web_push_subscription_id=wps_111, web_push_subscription_user_id=u_uuu)
2023/07/01 17:18:34 DEBUG HTTP request finished (http_method=POST, http_path=/testtopic, tag=http, time_taken_ms=3, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0007942666, visitor_seen=2023-07-01T17:18:34.742Z)
2023/07/01 17:18:35 DEBUG Sending web push message (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.11736104, visitor_seen=2023-07-01T17:18:34.742Z, web_push_subscription_endpoint=https://web.push.apple.com/long-id-2, web_push_subscription_id=wps_222, web_push_subscription_user_id=u_uuu)
2023/07/01 17:18:35 DEBUG Sending web push message (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.1515888602, visitor_seen=2023-07-01T17:18:34.742Z, web_push_subscription_endpoint=https://web.push.apple.com/long-id-3, web_push_subscription_id=wps_333, web_push_subscription_user_id=u_uuu)
2023/07/01 17:18:36 DEBUG Writing token update queue for 1 token(s) (tag=user_manager)

I only see that web.push.apple.com was used 3 times, but I test with 2 iPhones. I have used one iPhone for testing when you developed web push. This iPhone is unreliable over 50%. Because of this, I have deleted everything on my ntfy instance, but not the pub/priv keys and also delete the PWA and rebooted this iPhone. My 2nd iPhone was integrated after re-install & configure 2.6.1. This iPhone need very few time a send curl command.
Also wanted to note that I have set token expiration to 180 days for both iPhones. Unlimited is only possible when I create a token from the web interface, for example for curl.

One more info: I only allow sending messages with an authenticated user, no anonymous usage possible. Some relevant env variables:

NTFY_ENABLE_LOGIN=true
NTFY_AUTH_DEFAULT_ACCESS=deny-all

NTFY_CACHE_STARTUP_QUERIES=pragma journal_mode = WAL;pragma synchronous = normal;pragma temp_store = memory;pragma busy_timeout = 15000;vacuum;

NTFY_BEHIND_PROXY=true
<!-- gh-comment-id:1616024455 --> @helmut72 commented on GitHub (Jul 1, 2023): This is the log when both iPhones doesn't receive anything. Some IDs and IP are redacted: ``` 2023/07/01 17:18:34 DEBUG Rate limiters reset for visitor (visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=0, visitor_messages_limit=17280, visitor_messages_remaining=17280, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=60, visitor_seen=2023-07-01T17:18:34.739Z) 2023/07/01 17:18:34 DEBUG HTTP request started (http_method=POST, http_path=/testtopic, tag=http, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=0, visitor_messages_limit=17280, visitor_messages_remaining=17280, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=60, visitor_seen=2023-07-01T17:18:34.742Z) 2023/07/01 17:18:34 DEBUG Received message (http_method=POST, http_path=/testtopic, message_body_size=38, message_call=, message_delayed=false, message_email=, message_event=message, message_firebase=true, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_unifiedpush=false, message_user=u_uuu, tag=publish, topic=testtopic, topic_last_access=2023-07-01T17:18:03.578Z, topic_subscribers=0, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.000344566, visitor_seen=2023-07-01T17:18:34.742Z) 2023/07/01 17:18:34 DEBUG Adding message to cache (http_method=POST, http_path=/testtopic, message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=publish, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0004209716, visitor_seen=2023-07-01T17:18:34.742Z) 2023/07/01 17:18:34 DEBUG Publishing web push message to 3 subscribers (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0006140932, visitor_seen=2023-07-01T17:18:34.742Z) 2023/07/01 17:18:34 DEBUG Wrote 1 message(s) in 1.438762ms (tag=message_cache) 2023/07/01 17:18:34 DEBUG Sending web push message (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0007800004, visitor_seen=2023-07-01T17:18:34.742Z, web_push_subscription_endpoint=https://web.push.apple.com/long-id-1, web_push_subscription_id=wps_111, web_push_subscription_user_id=u_uuu) 2023/07/01 17:18:34 DEBUG HTTP request finished (http_method=POST, http_path=/testtopic, tag=http, time_taken_ms=3, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.0007942666, visitor_seen=2023-07-01T17:18:34.742Z) 2023/07/01 17:18:35 DEBUG Sending web push message (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.11736104, visitor_seen=2023-07-01T17:18:34.742Z, web_push_subscription_endpoint=https://web.push.apple.com/long-id-2, web_push_subscription_id=wps_222, web_push_subscription_user_id=u_uuu) 2023/07/01 17:18:35 DEBUG Sending web push message (message_body_size=38, message_event=message, message_id=zzz, message_sender=80.80.80.80, message_time=1688231914, message_user=u_uuu, tag=webpush, topic=testtopic, user_id=u_uuu, user_name=testuser, visitor_auth_limiter_limit=0.016666666666666666, visitor_auth_limiter_tokens=30, visitor_id=ip:80.80.80.80, visitor_ip=80.80.80.80, visitor_messages=1, visitor_messages_limit=17280, visitor_messages_remaining=17279, visitor_request_limiter_limit=0.2, visitor_request_limiter_tokens=59.1515888602, visitor_seen=2023-07-01T17:18:34.742Z, web_push_subscription_endpoint=https://web.push.apple.com/long-id-3, web_push_subscription_id=wps_333, web_push_subscription_user_id=u_uuu) 2023/07/01 17:18:36 DEBUG Writing token update queue for 1 token(s) (tag=user_manager) ``` I only see that web.push.apple.com was used 3 times, but I test with 2 iPhones. I have used one iPhone for testing when you developed web push. This iPhone is unreliable over 50%. Because of this, I have deleted everything on my ntfy instance, but not the pub/priv keys and also delete the PWA and rebooted this iPhone. My 2nd iPhone was integrated after re-install & configure 2.6.1. This iPhone need very few time a send curl command. Also wanted to note that I have set token expiration to 180 days for both iPhones. Unlimited is only possible when I create a token from the web interface, for example for curl. One more info: I only allow sending messages with an authenticated user, no anonymous usage possible. Some relevant env variables: ``` NTFY_ENABLE_LOGIN=true NTFY_AUTH_DEFAULT_ACCESS=deny-all NTFY_CACHE_STARTUP_QUERIES=pragma journal_mode = WAL;pragma synchronous = normal;pragma temp_store = memory;pragma busy_timeout = 15000;vacuum; NTFY_BEHIND_PROXY=true ```
Author
Owner

@nimbleghost commented on GitHub (Jul 1, 2023):

Hmm, if there's the DEBUG Publishing web push message to 3 subscribers line and no errors (e.g. an error from Apple's servers), it doesn't look like anything is wrong on the server side.

Some further notes for testing:

  • If you want to reset all web push subscribers you can simply delete the webpush.db file, it only stores a mapping of browser subscription endpoint (such as https://web.push.apple.com/<random-string>) and topic. No need to restart your iPhone or delete the PWA.
  • Token expiration has nothing to do with web push. Extra entries (e.g. you seeing 3 instead of 2) will automatically be removed: 7 days after the last time you opened the ntfy PWA, you first receive a warning, and then will automatically be unsubscribed on the 9th day if you don't open the app. These entries will also be cleaned up if the push service tells ntfy that the subscription isn't valid anymore (e.g. HTTP 410 Gone or other error).
  • You can try attaching your iPhone to a Mac, enabling Safari developer options on both devices, and then opening the two ntfy items in Develop > "Your iPhone", i.e. both the web app and the service worker for the web app. Send a message and you should see the service worker receiving it, and perhaps an error it is received but displaying the notification fails for some reason. If all this works, the only remaining possibility is that Apple is sometimes limiting these pushes for some reason.

The "real" way to fix this would be to track message delivery (e.g. have the PWA tell ntfy that the notification has been received) and then retry a notification after a certain time, but binwiederhier generally wants to avoid this as that's tracking the user, in a way.

<!-- gh-comment-id:1616065406 --> @nimbleghost commented on GitHub (Jul 1, 2023): Hmm, if there's the `DEBUG Publishing web push message to 3 subscribers` line and no errors (e.g. an error from Apple's servers), it doesn't look like anything is wrong on the server side. Some further notes for testing: - If you want to reset all web push subscribers you can simply delete the `webpush.db` file, it only stores a mapping of browser subscription endpoint (such as `https://web.push.apple.com/<random-string>`) and topic. No need to restart your iPhone or delete the PWA. - Token expiration has nothing to do with web push. Extra entries (e.g. you seeing 3 instead of 2) will automatically be removed: 7 days after the last time you opened the ntfy PWA, you first receive a warning, and then will automatically be unsubscribed on the 9th day if you don't open the app. These entries will also be cleaned up if the push service tells ntfy that the subscription isn't valid anymore (e.g. HTTP 410 Gone or other error). - You can try attaching your iPhone to a Mac, enabling Safari developer options on both devices, and then opening the two ntfy items in Develop > "Your iPhone", i.e. both the web app and the service worker for the web app. Send a message and you should see the service worker receiving it, and perhaps an error it is received but displaying the notification fails for some reason. If all this works, the only remaining possibility is that Apple is sometimes limiting these pushes for some reason. The "real" way to fix this would be to track message delivery (e.g. have the PWA tell ntfy that the notification has been received) and then retry a notification after a certain time, but binwiederhier generally wants to avoid this as that's tracking the user, in a way.
Author
Owner

@helmut72 commented on GitHub (Jul 1, 2023):

@nimbleghost

Thanks for explain some things!

The "real" way to fix this...

This means it's currently by design? Maybe the "real" way should be optionally enabled.

<!-- gh-comment-id:1616087900 --> @helmut72 commented on GitHub (Jul 1, 2023): @nimbleghost Thanks for explain some things! > The "real" way to fix this... This means it's currently by design? Maybe the "real" way should be optionally enabled.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ntfy#510
No description provided.