Bug 263687

Summary: notificationClick openWindow goes to PWA root instead of url given
Product: WebKit Reporter: Mark R <mark.romano>
Component: WebKit APIAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Major CC: beidson, bfulgham, conner, rniwa, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 17   
Hardware: iPhone / iPad   
OS: iOS 17   

Description Mark R 2023-10-25 15:08:56 PDT
Overview:

What I'm seeing is similar to https://bugs.webkit.org/show_bug.cgi?id=252544#c18 but I didn't find a logged bug.

Steps to Reproduce:

Service Worker handles push/notificationclick where the event data can contain a deeplink to open.
Install the PWA on Home Screen.
Close the PWA app.
Tap a Notification with a deeplink in the data.
notificationclick calls clients.openWindow() with the deeplink.

Actual Results:

PWA is opened, but to the pwa root url.

Expected Results:

PWA is opened to the deeplink url sent to openWindow().
This is the behavior seen if the PWA is already open.

Build Date & Hardware:

iPhone 14 MPUA3LL/A, iOS Version 17.0.3 (21A360)

Additional Information:

Contrary to the link above, I know that the service worker is handling the push event because I added "sw-" to the title sent to showNotification(), to confirm.

I also am struggling with similar Safari devtools behavior:
"In this case, I cannot open the Safari devtools for the service worker running on my phone, it simply isn't listed in the Develop menu under my phone submenu, which is really strange. If I open the app manually then the service worker appears in the menu as expected."


notificationclick handler calls a focus() function with parameters extracted from notification.data:

function focus(event, parameters) {
  const destinationUrl = (parameters && parameters.urlPath) ? new URL(parameters.urlPath, appPath).href : appPath;

  const matchOptions = {
    type: 'window',
    includeUncontrolled: false,
  };
  const result = globalThis.clients.matchAll(matchOptions)
    .then((windowClients) => {
      // See if there is client for this application already open
      const matchingClient = windowClients.find((windowClient) => windowClient.url.startsWith(appPath));

      if (matchingClient) {
        logger.info('Found a matching client, focussing it');
        if (destinationUrl !== appPath) {
          return matchingClient.navigate(destinationUrl).then(() => matchingClient.focus());
        }
        return matchingClient.focus();
      }

      logger.info('Opening a new client at', destinationUrl);
      return globalThis.clients.openWindow(destinationUrl)
        .catch((error) => {
          logger.error(`openWindow(${destinationUrl}) failed! ${error})`);
        });
    });

  event.waitUntil(result);
}
Comment 1 Mark R 2023-10-27 14:37:14 PDT
We have determined that it is actually the call to 
matchingClient.navigate(destinationUrl)
that is failing with "TypeError: navigate failed"

There are no windows open for the service worker, the PWA has been closed, and so has Safari.
Comment 2 Radar WebKit Bug Importer 2023-11-01 15:09:17 PDT
<rdar://problem/117817784>
Comment 3 Mark R 2023-12-05 11:18:40 PST
Are there any updates on why this isn't working properly?

As you can see in my snippet, we have a notificationclick message that can have a URL in it.

Basically we want to focus and navigate (or openWindow to the url if no client found).

It seems pretty straightforward, but users variably see different behaviors - sometimes the app is focused but doesn't navigate, sometimes the app doesn't even focus.

Is there a specific pattern to follow in a notificationclick event handler such that focus/navigate/openWindow always works on ios?
Comment 4 Ryosuke Niwa 2024-03-04 15:42:36 PST
This is a regression (i.e. used to work on some versions of iOS)?f
Comment 5 Mark R 2024-03-20 11:28:45 PDT
Are there any updates on this?