[GH-ISSUE #316] Bug: iOS notifications sometimes received twice #245

Closed
opened 2026-05-07 00:22:13 +02:00 by BreizhHardware · 14 comments

Originally created by @robfox92 on GitHub (Jun 7, 2022).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/316

I have a script that runs every day at 00:00, and will sometimes send a notification. This morning I saw two notifications on my phone - one at 00:00 and one at 00:07. On my (self-hosted) ntfy I only see a single notification in the web UI (at 00:00). In the ntfy ios app I also see a single notification for 00:00.

It seems like the popup notification was sent twice for some reason? I'll try and replicate it later today.

Originally created by @robfox92 on GitHub (Jun 7, 2022). Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/316 I have a script that runs every day at 00:00, and will sometimes send a notification. This morning I saw two notifications on my phone - one at 00:00 and one at 00:07. On my (self-hosted) ntfy I only see a single notification in the web UI (at 00:00). In the ntfy ios app I also see a single notification for 00:00. It seems like the popup notification was sent twice for some reason? I'll try and replicate it later today.
BreizhHardware 2026-05-07 00:22:13 +02:00
Author
Owner

@binwiederhier commented on GitHub (Jun 7, 2022):

Do they show in the UI twice? I am pretty sure I have experienced this as well, but I thought I imagined it. Since I don't use an iOS device myself during day to day, it is much less likely to happen to me.

Try hard-killing the app and seeing if you see one or two notifications in the list.

<!-- gh-comment-id:1148082615 --> @binwiederhier commented on GitHub (Jun 7, 2022): Do they show in the UI twice? I am pretty sure I have experienced this as well, but I thought I imagined it. Since I don't use an iOS device myself during day to day, it is much less likely to happen to me. Try hard-killing the app and seeing if you see one or two notifications in the list.
Author
Owner

@binwiederhier commented on GitHub (Jun 7, 2022):

Note to self: my guess is that this is another one of those Core Data inconsistencies across processes.

<!-- gh-comment-id:1148083172 --> @binwiederhier commented on GitHub (Jun 7, 2022): Note to self: my guess is that this is another one of those Core Data inconsistencies across processes.
Author
Owner

@robfox92 commented on GitHub (Jun 7, 2022):

I made the mistake of clearing the notifications before taking a screenshot - I'm trying to replicate again and will grab one if I can.

The duplicate notifications just appeared in the notifications tray. Only a single one showed in the ntfy app.

Site note - how do I put a label on this issue?

<!-- gh-comment-id:1148085807 --> @robfox92 commented on GitHub (Jun 7, 2022): I made the mistake of clearing the notifications before taking a screenshot - I'm trying to replicate again and will grab one if I can. The duplicate notifications just appeared in the notifications tray. Only a single one showed in the ntfy app. Site note - how do I put a label on this issue?
Author
Owner

@robfox92 commented on GitHub (Jun 7, 2022):

It's potentially related to "do not disturb" mode. I just turned it on, sent 1 notification via the web ui and after a few minutes I turned off dnd mode.

image

image

<!-- gh-comment-id:1148134061 --> @robfox92 commented on GitHub (Jun 7, 2022): It's potentially related to "do not disturb" mode. I just turned it on, sent 1 notification via the web ui and after a few minutes I turned off dnd mode. ![image](https://user-images.githubusercontent.com/9668927/172284935-34537114-ea5f-46a8-9ade-b3af8c20fe29.png) ![image](https://user-images.githubusercontent.com/9668927/172285053-57325d47-2bcf-4fc4-953d-c30007ba37bd.png)
Author
Owner

@binwiederhier commented on GitHub (Jun 8, 2022):

That's a good lead, thank you. I'll investigate this when I get to it.

Here's my current hunch:

Every 20 minutes or so, the app polls for new messages from the server. If a message is not in the local database, it'll display it as a local notification. If the remote message eventually arrives via Firebase, there is no way for me to silence the notification. It's impossible without the "notification filtering entitlement", which Apple denied me when I requested it.

It could be that in DND mode, messages arrive neither via Firebase, nor is polling allowed to execute. Once you come out of DND, both run at the same time and race, and two notifications are displayed. That's just a guess though. I'd have to test it.

<!-- gh-comment-id:1149299459 --> @binwiederhier commented on GitHub (Jun 8, 2022): That's a good lead, thank you. I'll investigate this when I get to it. Here's my current hunch: Every 20 minutes or so, the app polls for new messages from the server. If a message is not in the local database, it'll display it as a local notification. If the remote message eventually arrives via Firebase, there is no way for me to silence the notification. It's impossible without the "notification filtering entitlement", which Apple denied me when I requested it. It could be that in DND mode, messages arrive neither via Firebase, nor is polling allowed to execute. Once you come out of DND, both run at the same time and race, and two notifications are displayed. That's just a guess though. I'd have to test it.
Author
Owner

@milksteakjellybeans commented on GitHub (Jun 12, 2022):

I got this overnight. I have a parrot tell me everything is still working at 4am.

Latest iOS app, Latest ntfy server via docker self hosted, it was during nightly fixed DND time for both notifications. Screen shots if it's helpful.

Screen Shot 2022-06-12 at 08 59 39 Screen Shot 2022-06-12 at 09 01 03
<!-- gh-comment-id:1153220512 --> @milksteakjellybeans commented on GitHub (Jun 12, 2022): I got this overnight. I have a parrot tell me everything is still working at 4am. Latest iOS app, Latest ntfy server via docker self hosted, it was during nightly fixed DND time for both notifications. Screen shots if it's helpful. <img width="432" alt="Screen Shot 2022-06-12 at 08 59 39" src="https://user-images.githubusercontent.com/106365477/173242240-ea28efeb-252d-4c6d-84cd-c5718214ed38.png"> <img width="427" alt="Screen Shot 2022-06-12 at 09 01 03" src="https://user-images.githubusercontent.com/106365477/173242299-f96f653a-7b0f-44c7-aad4-a133b953c737.png">
Author
Owner

@binwiederhier commented on GitHub (Jun 12, 2022):

Thanks. Definitely helpful to confirm it. I wish I could ask you for logs, but I haven't figured out how to write/persist them in iOS so you can share them (like I did in Android). That would make things so much easier.

<!-- gh-comment-id:1153221636 --> @binwiederhier commented on GitHub (Jun 12, 2022): Thanks. Definitely helpful to confirm it. I wish I could ask you for logs, but I haven't figured out how to write/persist them in iOS so you can share them (like I did in Android). That would make things so much easier.
Author
Owner

@robfox92 commented on GitHub (Jun 13, 2022):

I set up a cron job to send myself a notification at 1am every day (while quiet hours are on) and this morning the notifications had timestamps of 01:00 and 01:15.

Are more screenshots helpful at this point?

If you get a testflight build set up to try and pinpoint this I'm keen to run it.

<!-- gh-comment-id:1153334115 --> @robfox92 commented on GitHub (Jun 13, 2022): I set up a cron job to send myself a notification at 1am every day (while quiet hours are on) and this morning the notifications had timestamps of 01:00 and 01:15. Are more screenshots helpful at this point? If you get a testflight build set up to try and pinpoint this I'm keen to run it.
Author
Owner

@milksteakjellybeans commented on GitHub (Jun 17, 2022):

It seems like what might be happening here is that the iOS instant notification is received and if there is no interaction with the phone or ntfy app, the non-instant version of the notification also eventually makes its way to the phone and you get the double notification. This is only conjecture from my observations using the iOS app and not anything deeper than that. (and I have not upgraded beyond 1.25.2 server yet)

<!-- gh-comment-id:1159253452 --> @milksteakjellybeans commented on GitHub (Jun 17, 2022): It seems like what might be happening here is that the iOS instant notification is received and if there is no interaction with the phone or ntfy app, the non-instant version of the notification also eventually makes its way to the phone and you get the double notification. This is only conjecture from my observations using the iOS app and not anything deeper than that. (and I have not upgraded beyond 1.25.2 server yet)
Author
Owner

@majoragee commented on GitHub (Jul 16, 2022):

I can also confirm duplicate notifications arriving 5-15 minutes later than the original. I will add that I do not use Do Not Disturb but I still experience the issue when I don't open the app to look at the notification. The correlation to Do Not Disturb may be a coincidence. The app itself does not show duplicate messages - the issue is only with notifications.

I've been loving this service and the new iOS app. Keep up the great work!

<!-- gh-comment-id:1186218146 --> @majoragee commented on GitHub (Jul 16, 2022): I can also confirm duplicate notifications arriving 5-15 minutes later than the original. I will add that I do not use Do Not Disturb but I still experience the issue when I don't open the app to look at the notification. The correlation to Do Not Disturb may be a coincidence. The app itself does not show duplicate messages - the issue is only with notifications. I've been loving this service and the new iOS app. Keep up the great work!
Author
Owner

@binwiederhier commented on GitHub (Jul 27, 2022):

So my guess is that this is caused by two things:

  1. The first message is received via Firebase/APNS and persisted to Core Data. Messages received via APNS run in the Notification Service Extension (NSE), not in the main app. They do, however, persist to the same Core Data database.
  2. The second message is received from the polling mechanism: Every 20 minutes or so, the app receives a "poll all topics" message on the internal ~poll topic. That will instruct the main app to poll for new messages. To find out the last message it received, it uses the lastNotificationId field and then polls using /mytopic/json?since=$id. This ID is coming from Core Data.

The issue is this (this is a GUESS!): The Core Data database is not properly in sync between the main app and the NSE, which means the lastNotificationId is out of sync, so messages are delivered/displayed twice. This is bug https://github.com/binwiederhier/ntfy/issues/316.

This causes another bug too, where the UI does not reflect all messages all the time (this is: https://github.com/binwiederhier/ntfy/issues/337). It is annoying and it just shows that I don't know how Core Data works internally. It could also be a bug, but it's annoying.

Again, this is just a guess.

Debugging this is next to impossible, because

  • (a) You'll have to compile and run the iOS app yourself and hook it up to Firebase and APNS. It doesn't work in a Simulator because Firebase doesn't work in a simulator.
  • (b) Because the NSE is a separate process, the logs for it do not show up in the log console of Xcode. You have to manually attach a debugger and such. It is surpremely annoying.

Before you ask "what the heck": 90% of this is Apple's fault, of how the NSE and all that work. The problem with Core Data is obviously my fault, but I have no time currently to debug this or spend any time with it.

<!-- gh-comment-id:1197486221 --> @binwiederhier commented on GitHub (Jul 27, 2022): So my guess is that this is caused by two things: 1. The first message is received via Firebase/APNS and persisted to Core Data. Messages received via APNS run in the Notification Service Extension (NSE), not in the main app. They do, however, persist to the same Core Data database. 2. The second message is received from the polling mechanism: Every 20 minutes or so, the app receives a "poll all topics" message on the internal ~poll topic. That will instruct the main app to poll for new messages. To find out the last message it received, it uses the `lastNotificationId` field and then polls using `/mytopic/json?since=$id`. This ID is coming from Core Data. The issue is this (this is a GUESS!): The Core Data database is not properly in sync between the main app and the NSE, which means the `lastNotificationId` is out of sync, so messages are delivered/displayed twice. This is bug https://github.com/binwiederhier/ntfy/issues/316. This causes another bug too, where the UI does not reflect all messages all the time (this is: https://github.com/binwiederhier/ntfy/issues/337). It is annoying and it just shows that I don't know how Core Data works internally. It could also be a bug, but it's annoying. Again, this is just a guess. Debugging this is next to impossible, because - (a) You'll have to compile and run the iOS app yourself and hook it up to Firebase and APNS. It doesn't work in a Simulator because Firebase doesn't work in a simulator. - (b) Because the NSE is a separate process, the logs for it do not show up in the log console of Xcode. You have to manually attach a debugger and such. It is surpremely annoying. Before you ask "what the heck": 90% of this is Apple's fault, of how the NSE and all that work. The problem with Core Data is obviously my fault, but I have no time currently to debug this or spend any time with it.
Author
Owner

@notDavid commented on GitHub (Nov 9, 2022):

Fyi, arriving shortly after another within a few seconds (i think it was less than ~ 10 seconds.) Can not reproduce again right after this screenshot...

IMG_1438

<!-- gh-comment-id:1308850420 --> @notDavid commented on GitHub (Nov 9, 2022): Fyi, arriving shortly after another within a few seconds (i think it was less than ~ 10 seconds.) Can not reproduce again right after this screenshot... ![IMG_1438](https://user-images.githubusercontent.com/1530401/200853654-3b3208a8-d501-461f-ab12-c56a13f5e487.png)
Author
Owner

@ghost commented on GitHub (Jan 30, 2023):

Seeing the same issue. Self hosted install. Notifications always seem to be 7 minutes apart.

  • I do use DND but pretty sure it's not always on when I receive the duplicate notifications, but mostly happens at night
  • Checked my script logs to make sure it only executed once around that time
  • Only one notification shows within the iOS app and web UI at the time of the original run (not the 7 minutes later)
  • upstream-base-url: "https://ntfy.sh" is set for instant notifications

Thanks for everything

<!-- gh-comment-id:1408095363 --> @ghost commented on GitHub (Jan 30, 2023): Seeing the same issue. Self hosted install. Notifications always seem to be 7 minutes apart. - I do use DND but pretty sure it's not always on when I receive the duplicate notifications, but mostly happens at night - Checked my script logs to make sure it only executed once around that time - Only one notification shows within the iOS app and web UI at the time of the original run (not the 7 minutes later) - upstream-base-url: "https://ntfy.sh" is set for instant notifications Thanks for everything
Author
Owner

@binwiederhier commented on GitHub (Mar 31, 2023):

I do believe this is fixed by #677/#509 -- If it still happens, please comment here and I'll re-open.

<!-- gh-comment-id:1491159758 --> @binwiederhier commented on GitHub (Mar 31, 2023): I do believe this is fixed by #677/#509 -- If it still happens, please comment here and I'll re-open.
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#245
No description provided.