RESOLVED FIXED 275797
macOS: setAppBadge() not called by service worker if pwa is closed
https://bugs.webkit.org/show_bug.cgi?id=275797
Summary macOS: setAppBadge() not called by service worker if pwa is closed
aikawa-kazuki
Reported 2024-06-23 19:16:29 PDT
Overview In macOS Safari PWA, executing navigator.setAppBadge(num) from a service worker does not update the icon when the PWA is not running. - The notification banner is displayed as expected. - It works as expected on iOS. - It displays correctly when the PWA is running. There are others experiencing the same issue on Stack Overflow. https://stackoverflow.com/questions/78472771/macos-setappbadge-not-called-by-service-worker-if-pwa-installed-web-app-is-c Steps to Reproduce: Using code from https://webkit.org/blog/14112/badging-for-home-screen-web-apps/ self.addEventListener('push', (event) => { let promises = []; if ('setAppBadge' in self.navigator) { const promise = self.navigator.setAppBadge(3); promises.push(promise); } // Promise to show a notification promises.push(self.registration.showNotification("You've got mail!")); // Finally... event.waitUntil(Promise.all(promises)); }); Send a push notification from Firebase Cloud Messaging. Actual Results: Nothing happens. Additionally, the service worker debugger in Safari cannot be accessed when the app is not running. Expected Results: The badge on the dock icon should be updated. Build Date & Hardware: macOS Sonoma 14.5 (23F79) Safari 17.5 (19618.2.12.11.6) I am posting this issue as it might be a macOS bug, but there is also a possibility it could be on the Webkit side. Thank you for your consideration. Please let us know if you need any other information.
Attachments
Radar WebKit Bug Importer
Comment 1 2024-06-24 09:48:45 PDT
Ahmad Saleem
Comment 2 2024-06-25 07:28:32 PDT
@Aikawa - is it something start happening with 17.5 or it was not working in prior versions as well?
aikawa-kazuki
Comment 3 2024-06-25 21:42:36 PDT
Thank you for your response. I noticed the issue with Safari 17.5. Unfortunately, I do not have access to a macOS with an earlier version of Safari to test. Someone else reported on Stack Overflow that the issue is also occurring on macOS Sonoma 14.4.1 with Safari 17.4.1.
aikawa-kazuki
Comment 4 2024-10-01 23:50:58 PDT
The issue persists on macOS Sequoia 15.0 with Safari 18.0. As this is a critical aspect of the application’s user experience, I would like to request that this issue be prioritized. Additionally, I would appreciate any guidance on possible workarounds that we could implement on our end. Thank you for your assistance.
aikawa-kazuki
Comment 5 2024-10-10 23:06:28 PDT
Dear Brady, Thank you for looking into the issue I reported. I wanted to ask if there have been any updates or if you were able to reproduce the issue on your end. If you need any additional information from me, please don’t hesitate to let me know. I appreciate your time and efforts on this matter. Best regards,
Ben Nham
Comment 6 2024-10-23 15:19:14 PDT
The data flow for this feature in WebKit is relatively simple. WebKit just asks the embedder (Web App) to set a badge via its _WKWebsiteDataStoreDelegate. So I don't think there is a bug in WebKit. However, I had a look at Web App, and it looks it can fire a push event to the service worker before it sets the delegate property on WKWebsiteDataStore. In that case, if the push event handler executes quickly enough, then it might call setAppBadge before the delegate is set. In that case, the app badge update would just get dropped on the floor, since there is no delegate for WebKit to pass the badge update to. So this looks like a Web App rather than WebKit bug to me at first glance, but I will do a bit more digging.
aikawa-kazuki
Comment 7 2024-10-23 22:46:19 PDT
Thank you for your detailed response regarding the issue with setAppBadge in Safari PWA. Based on your feedback, I have created a test environment on GitHub to reproduce the issue. You can clone the repository and test it locally to observe the behavior. The code for the service worker is copied from the WebKit blog. https://webkit.org/blog/14112/badging-for-home-screen-web-apps/ Here is the link to the GitHub repository: https://github.com/AikawaKazuki/pwa-badge.git Steps to reproduce the issue: 1. Clone the repository and run it locally. For more details, refer to README.md. 2. Register the service worker and trigger a push event that attempts to call navigator.setAppBadge(). Observed behavior: - When the PWA is running, receiving a notification causes the badge count to change. - When the PWA is not running, receiving a notification does not change the badge count. - After receiving two push notifications while the PWA is not running, a black dot appears under the Dock icon, indicating the app is running, but the app is not actually active. Please feel free to use the provided code and steps to reproduce the behavior. I look forward to any further insights you may have after investigating this issue. If it is a bug with the embedder (Web App), what should I do to resolve it? I already reported the bug on https://feedbackassistant.apple.com/feedback/15355991 . Thank you for your support.
Ben Nham
Comment 8 2024-10-25 17:33:18 PDT
Ok, I see the problem and why repro'd on some devices but not others. The thing I wrote above with -openURL: being handled before -applicationDidFinishLaunching can theoretically happen, but it doesn't look like what was causing the issue. Basically, when setting the badge doesn't work, it's because setAppBadge is not accessible on ServiceWorkerGlobalScope. This is because setAppBadge is enabled by the preference AppBadgeEnabled (see NavigatorBadge.idl). Web App only enables AppBadgeEnabled the first time it creates any WKWebView. If this web view is initialized early enough (earlier than when the service worker starts), then the service worker will inherit the AppBadgeEnabled setting from that first web view (see the part of WebProcessPool::createWebPage that sets m_remoteWorkerPreferences). This was actually happening on one of my devices, which is why I couldn't repro the issue on that device. On that device, I have some extensions enabled in Web App, and extensions create WKWebViews with the AppBadgeEnabled preference set early on during process launch. That preference carries over to the service worker once it's spawned (see the part of WebProcessPool::establishRemoteWorkerContextConnectionToNetworkProcess which initializes the Service Worker's preferences with m_remoteWorkerPreferences). In the buggy case, the service worker spawns before any WKWebView in the process pool is created, and m_remoteWorkerPreferences is null when WebProcessPool::establishRemoteWorkerContextConnectionToNetworkProcess spawns the service worker. In this case, the service worker just gets the default value for AppBadgeEnabled, which is false. What is supposed to happen is that Mac Web App should provide sensible default settings for service workers (e.g. enabling app badge) by using -[WKWebsiteDataStore _setServiceWorkerOverridePreferences:], but it doesn't. iOS Web App actually does this, but that code is missing from Mac Web App. So the fix here is to basically have Mac Web App set initial settings for service workers via -[WKWebsiteDataStore _setServiceWorkerOverridePreferences:]. I don't own Web App, but I have the ability to write PRs for it, so I will do that internally. Unfortunately, I don't see a good workaround until a fixed version of Mac Web App is released, since Mac Web App is just missing a call to -[WKWebsiteDataStore _setServiceWorkerOverridePreferences:]. Since that call is missing, service workers that spawn before any web views are created are spawned with the incorrect preferences, including the preference that enables app badges. If you just want this working on your own device, then enabling an extension for Web App might get app badges for closed Mac Web Apps to work for you. That workaround might only work on macOS 15+ because the way that extension integration works changed a lot in macOS 15.
aikawa-kazuki
Comment 9 2024-10-28 00:08:16 PDT
Thank you for your response and for looking into this issue. We appreciate that, although you do not directly manage Web App, you are planning to create a PR and handle it internally. We have considered the suggested workaround, but as this app is intended for end-users, it would be challenging to ask each user to enable the Web App extension. This makes it difficult to implement the workaround in a practical sense. With this in mind, could you provide some information regarding the official release of the fix? Specifically, do you know in which version of macOS this fix might be included, and if there is a possibility it will be part of the next minor update? We would appreciate any updates regarding the progress on this issue. Thank you very much for your assistance.
Ben Nham
Comment 10 2024-10-30 09:42:03 PDT
I can't comment specifically on future releases. However, I did submit a PR with a fix for Web.app and got it integrated into the codebase earlier this week. So this fix should ship as part of both an upcoming macOS Sequoia release as well as an upcoming Safari 18.x update for previous macOSes (as Web.app is part of the Safari 18.x update bundles). Since this is not a WebKit bug but rather a macOS bug with Web.app, I'm going to close this bug. However, you will be able to track the status of when Web.app gets the fix in the Feedback Assistant report you filed. I found the Feedback Assistant report you filed in the internal bug tracking database and related the fix I submitted to that report so that the report should get updated when the fix is released.
aikawa-kazuki
Comment 11 2024-10-30 23:58:14 PDT
Thank you for the update. I appreciate the work you’ve done to submit the PR and ensure the fix is integrated for both the upcoming macOS Sequoia release and Safari 18.x update. I’ll keep an eye on the Feedback Assistant report for further updates. Thank you again!
Note You need to log in before you can comment on or make changes to this bug.