Skip to content

[Bug]: Service worker event listeners don't work in iOS if app is opened from home screen. #7309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
stefan-krajnik opened this issue May 18, 2023 · 30 comments

Comments

@stefan-krajnik
Copy link

stefan-krajnik commented May 18, 2023

Operating System

iOS 16.4.1 (a)

Browser Version

Safari

Firebase SDK Version

9.22.0

Firebase SDK Product:

Messaging

Describe your project's tooling

NodeJs Express

Describe the problem

In the demo app, I listen on messages posted from service worker.
As you can see in the video on desktop Safari it works as intended but it doesn't on iOS (16.4.1 (a) - iPhone 8)

With further investigation I found out event listeners in service workers are not always called,
if I open the app from home screen clicks on notification don't do anything, but if the app is opened by click on notification then it works as intended, meaning clicks on next notification trigger event listeners in service worker.

Screen.Recording.2023-05-18.at.4.21.34.PM.mp4

Steps and code to reproduce issue

  • Save the app to Home screen
  • Open the app and allow notoficitations, wait for token to be generated
  • Close the app
  • Reopen the app
  • Click "Notify all"
  • Click on received notification

Here you can see the reproduction demo https://github.com/stefan-krajnik/fcm-web-push-example
Provide correct firebase config here - https://github.com/stefan-krajnik/fcm-web-push-example/blob/master/index.html#L80
Generate Firebase Admin SDK private key and provide correct path to it - https://github.com/stefan-krajnik/fcm-web-push-example/blob/master/server.js#L5

I deployed the reproduction app to https://fcm-webpush-test.onrender.com

@looptheloop88
Copy link

Hi @stefan-krajnik, I'm not sure if I understood the issue well so correct me if I'm wrong here. If the web app is open, you send a notification and the app receives it successfully, you click the notification, it doesn't redirect to the target page.

I checked the code reproduction you've shared and I noticed the way you handle creating and receiving of the notification are different from our documentation and quickstart project. You're not using the onMessage and onBackgroundMessage callbacks available in the Messaging SDK.

Could you please try to use the suggested implementation and see if the issue persists?

@stefan-krajnik
Copy link
Author

Hey @looptheloop88 , thanks for replying.

correct me if I'm wrong here. If the web app is open, you send a notification and the app receives it successfully, you click the notification, it doesn't redirect to the target page.
Yes that's correct. But only if the app is open, if app is completely closed, the notification click works properly as expected.

I implemented your suggestion, you can check it out. The behavior is a little bit different from the initial one but the issue is still there, clicking on notification when the app is opened doesn't do anything.

@looptheloop88
Copy link

Hi @stefan-krajnik, could you please verify if onMessage callback is triggered when the message is received while the app has focus or is currently opened? I would like to isolate the possible cause, since the notification is created locally and not by the FCM SDK.

@stefan-krajnik
Copy link
Author

@looptheloop88
No onMessage is not triggered if the app is opened from the homescreen.

@Heerschop
Copy link

I'm experiencing the same problem, however I do not think this has anything to do with Firebase. I have tried several different implementations, and they all have the same issue. For example:

I think this problem is related to Safari 16 WebKit API as described in this bug report: https://bugs.webkit.org/show_bug.cgi?id=252544

Here's what happens:
1 - The app launches and starts a page load for the root URL of the web app - https://taoshu.in/web/push-demo/ in this case. This happens in web content process A.
2 - That load has a ScriptExecutionContextIdentifier associated with it. Importantly, this identifier is what the eventual Document will have, but that document does not exist yet.
3 - The networking process is asked to load https://taoshu.in/web/push-demo/. As part of that resource load it is given the context identifier. So the networking process remembers "There is a window client for this URL with this identifier.
4 - The service worker is fired up in web content process B to handle the notification click. This happens right away, before the main page document has really started loading.
5 - In the notification click handler, the SW does a matchAll on clients looking for window clients
6 - That matchAll goes to the networking process, which knows about the eventual client. So it returns that UUID
7 - Back in web content B, the SW has the results of the matchAll and tries to call focus() on the window client.
8 - That focus call is routed to the networking process based on UUID, which knows that the document should be in Web Content process A. So it forwards the call there
9 - In Web Content process A, the focus() attempt tries to look up the Document for that UUID and fails. Remember from step 2, the eventual Document that will be created will have that UUID, but that Document doesn't exist yet.
10 - The failure is routed to Networking, which then routes to Web Content B, and then rejects the focus() promise. Whoops!
11 - Almost immediately after that rejection, data does come in for the main page document, therefore actually creating the Document object in Web Content A, ensuring that a future focus() call would actually work.

A PR has been merged for this: WebKit/WebKit#11848, but it will probably take a while for this to end up in Safari.

@Heerschop
Copy link

Just as a note: I have experienced when you add and remove the site from the home screen several times, every so often you will end up with a fully working version, let's say one out of every 15 attempts.

@taoso
Copy link

taoso commented May 30, 2023

@Heerschop Here is my screen record.

I call the API with data=123. After I click the notification, the data in the bottom of the page changed to 123.

This is done by the following code

navigator.serviceWorker.addEventListener("message", (event) => {
  let wn = document.getElementById("web-notification");
  wn.innerHTML = event.data;
});

So please do not repeat the issue not fixed. Offer the minimal code to reproduce it.
Please offer code use the native API. I do not think there will be anyone willing to debug firebase's framework.

2_1685427976.mp4

@Heerschop
Copy link

Heerschop commented May 30, 2023

@taoso Thank you so much for sharing.

I have seen your version work, on my device as well. But when I removed it from the home screen and added it back, it didn't work anymore. I have tested this on Beta iOS 16.6. I can restore it to a working version by adding and removing it several times, eventually I will have a working version again.

@jbalidiong
Copy link
Contributor

Hi @stefan-krajnik, I'll be taking over this issue from @looptheloop88. I was able to replicate the behavior wherein onMessage() is not triggered if the app is opened from home screen. It looks like this is more of a Safari issue. However, I'll check this with our FCM team to see what we can do for this issue. I’ll update this thread if I have any information to share.

@jbalidiong
Copy link
Contributor

Hi all, just an update from our investigation with the engineers. This is more likely a Safari issue and the details from #7309 (comment) are spot on. I'll leave this issue open for tracking until the PR is released on Safari's end.

@MYKEU
Copy link

MYKEU commented Jul 5, 2023

Experiencing this exact same issue - notification clicks works only if I open my app from a notification.

Curious if anyone has further updates regarding this?

@Sisyphusean
Copy link

Having this same issue. Moving to server sent event for iOS messages. Notifications will be only in app.

@DellaBitta
Copy link
Contributor

DellaBitta commented Aug 8, 2023

Hi @MYKEU and @Sisyphusean,

Please see the comment from @jbalidiong above. We believe this to be an issue in WebKit, which has been patched but it requires that Safari incorporate the fix and distribute a new release of Safari. I hope this helps.

@goetzrobin
Copy link

goetzrobin commented Oct 27, 2023

@Heerschop Here is my screen record.

I call the API with data=123. After I click the notification, the data in the bottom of the page changed to 123.

This is done by the following code

navigator.serviceWorker.addEventListener("message", (event) => {
  let wn = document.getElementById("web-notification");
  wn.innerHTML = event.data;
});

So please do not repeat the issue not fixed. Offer the minimal code to reproduce it. Please offer code use the native API. I do not think there will be anyone willing to debug firebase's framework.

2_1685427976.mp4

@taoso thank you for sharing this. I know it has been quite some time, but I just tested this on iOS 17 and it seems to be broken again. Do you see the same issue on your device?

@taoso
Copy link

taoso commented Oct 27, 2023

@goetzrobin I have rechecked, it still works.

Here is a live demo https://bugs.webkit.org/show_bug.cgi?id=252544#c3

@goetzrobin
Copy link

goetzrobin commented Oct 28, 2023

@goetzrobin I have rechecked, it still works.

Here is a live demo https://bugs.webkit.org/show_bug.cgi?id=252544#c3

@taoso Thanks for checking! This is really weird. I don't know what it is but on my phone I simply do not get it to work correctly. Here is a screen recording of me not getting the custom data: https://share.icloud.com/photos/073J3LdefkwK8XXsrWHxyalag

Let me know what you think!

@ereshidov
Copy link

ereshidov commented Jan 23, 2024

@goetzrobin I have rechecked, it still works.
Here is a live demo https://bugs.webkit.org/show_bug.cgi?id=252544#c3

@taoso Thanks for checking! This is really weird. I don't know what it is but on my phone I simply do not get it to work correctly. Here is a screen recording of me not getting the custom data: https://share.icloud.com/photos/073J3LdefkwK8XXsrWHxyalag

Let me know what you think!

Hi :)
were you able to figure out what the problem was?

@nmalzieu
Copy link

nmalzieu commented Jan 27, 2024

Hi there! I have the exact same issue on iOS 17.2.1

If I kill my PWA, then send a notification and click on it, the notificationclick event is triggered, and if I send other notifications and click on them, the notificationclick events are triggered (wether the PWA is foreground or background).

However, if I kill my PWA, then open it from the home screen, if I send notifications, click on them, the notificationclick event is never triggered.

N.B.: to detect if notificationclick is triggered I tried many things: postMessage to the client, fetch a specific URI on my server where I can detect it was called, etc. Always the same behaviour, it just seems the notificationclick event is not subscribed when app has been opened manually from the home screen on iOS (i.e. not via clicking a notification)

I'm not 100% sure this is the same thing as https://bugs.webkit.org/show_bug.cgi?id=252544 because when I try to trigger a fetch to an URI on my server, I don't think safari would care that a client is available, it's just the service worker that executes? Maybe I'm wrong though

@ereshidov
Copy link

Hi there! I have the exact same issue on iOS 17.2.1

If I kill my PWA, then send a notification and click on it, the notificationclick event is triggered, and if I send other notifications and click on them, the notificationclick events are triggered (wether the PWA is foreground or background).

However, if I kill my PWA, then open it from the home screen, if I send notifications, click on them, the notificationclick event is never triggered.

N.B.: to detect if notificationclick is triggered I tried many things: postMessage to the client, fetch a specific URI on my server where I can detect it was called, etc. Always the same behaviour, it just seems the notificationclick event is not subscribed when app has been opened manually from the home screen on iOS (i.e. not via clicking a notification)

I'm not 100% sure this is the same thing as https://bugs.webkit.org/show_bug.cgi?id=252544 because when I try to trigger a fetch to an URI on my server, I don't think safari would care that a client is available, it's just the service worker that executes? Maybe I'm wrong though

seems like this problem is not related to firebase sdk, i have exact same problem on iOS 17.2.1 using vite and my own web push configuration (web-push on server and my own service worker file)

@goetzrobin
Copy link

Hi there! I have the exact same issue on iOS 17.2.1

If I kill my PWA, then send a notification and click on it, the notificationclick event is triggered, and if I send other notifications and click on them, the notificationclick events are triggered (wether the PWA is foreground or background).

However, if I kill my PWA, then open it from the home screen, if I send notifications, click on them, the notificationclick event is never triggered.

N.B.: to detect if notificationclick is triggered I tried many things: postMessage to the client, fetch a specific URI on my server where I can detect it was called, etc. Always the same behaviour, it just seems the notificationclick event is not subscribed when app has been opened manually from the home screen on iOS (i.e. not via clicking a notification)

I'm not 100% sure this is the same thing as https://bugs.webkit.org/show_bug.cgi?id=252544 because when I try to trigger a fetch to an URI on my server, I don't think safari would care that a client is available, it's just the service worker that executes? Maybe I'm wrong though

this is exactly what I am experiencing! Good to know I am not going insane at least!

@nmalzieu
Copy link

I agree, seems to be an Apple / Safari / Webkit issue and not a firebase issue. Also, I don't think it is the same as https://bugs.webkit.org/show_bug.cgi?id=252544 - this one is fixed and supposedly live in "the latest iOS 16 and 17 betas" from a message sent 2023-06-07…
Should we open a new webkit issue?

@ereshidov
Copy link

ereshidov commented Jan 30, 2024

I agree, seems to be an Apple / Safari / Webkit issue and not a firebase issue. Also, I don't think it is the same as https://bugs.webkit.org/show_bug.cgi?id=252544 - this one is fixed and supposedly live in "the latest iOS 16 and 17 betas" from a message sent 2023-06-07… Should we open a new webkit issue?

Agreed, let's open a new ticket

Ping me on linkedin or twitter if you will need help with testing or code examples maybe

@DoronTorangy
Copy link

DoronTorangy commented May 25, 2024

For me 'notificationclick' doesn't work at all on iOS, it also states that in here.

I'm testing on iOS 17.4.1.
I do receive notifications just fine (I use FCM) but click does not work:

service-worker.ts

firebase.initializeApp(firebaseConfig)
const messaging = firebase.messaging()

messaging.onBackgroundMessage(payload => {
  console.log('This is called just fine', payload)
})

self.addEventListener('notificationclick', (event: any) => {
  console.log('NEVER CALLED, REGARDLESS IF APP IS DEAD, IN BACKGROUND OR IN FOREGROUND')
})

my-messaging-server.ts

...
await messaging.sendEach([
  ...,
  {
            token: "...",
            data: {
              ...
            },
            notification: {
              title: "Hello",
              body: "World",
            },
            webpush: {
              fcmOptions: {
                link: `/some-link-in-app`,
              },
            },
  }
])

On Android it automatically opens webpush.fcmOptions.link

@egorlitsky
Copy link

@DoronTorangy this is because you define notificationclick event-listener after loading a library.
I've had the same issue. Refer firebase/quickstart-js#102 for more details.

@dlarocque
Copy link
Contributor

For me 'notificationclick' doesn't work at all on iOS, it also states that in here.

I'm testing on iOS 17.4.1. I do receive notifications just fine (I use FCM) but click does not work:

service-worker.ts

firebase.initializeApp(firebaseConfig)
const messaging = firebase.messaging()

messaging.onBackgroundMessage(payload => {
  console.log('This is called just fine', payload)
})

self.addEventListener('notificationclick', (event: any) => {
  console.log('NEVER CALLED, REGARDLESS IF APP IS DEAD, IN BACKGROUND OR IN FOREGROUND')
})

my-messaging-server.ts

...
await messaging.sendEach([
  ...,
  {
            token: "...",
            data: {
              ...
            },
            notification: {
              title: "Hello",
              body: "World",
            },
            webpush: {
              fcmOptions: {
                link: `/some-link-in-app`,
              },
            },
  }
])

On Android it automatically opens webpush.fcmOptions.link

If you are still experiencing this issue, please open a new bug in this repository.

I've not been able to reproduce this issue with Firebase 10.13.0, and Safari 17.6- so please mention what versions you're using when you submit the issue and steps to reproduce.

@dlarocque
Copy link
Contributor

Seeing as the WebKit bug that has been causing this issue has been closed, and I'm not longer able to replicate the issue using latest Safari and Firebase versions, I believe this bug has been fixed.

Is anyone still experiencing this issue in the latest Safari and Firebase versions? If so, please share a full minimal reproduction that will help me confirm the bug.

@snovakovic
Copy link

@dlarocque We can still replicate this issue on latest iOS version (17.6.1). One thing to mention is that we tried on multiple devices and on some devices we where not able to replicate issue while on others we had same issue as this post explains when once in a while it works but most of the times it don't
#7309 (comment)

Have you been able to confirm it works reliably on multiple devices?

@atgillette
Copy link

It's still happening for me with 17.6.1.

@dlarocque
Copy link
Contributor

dlarocque commented Aug 29, 2024

@dlarocque We can still replicate this issue on latest iOS version (17.6.1). One thing to mention is that we tried on multiple devices and on some devices we where not able to replicate issue while on others we had same issue as this post explains when once in a while it works but most of the times it don't #7309 (comment)

Have you been able to confirm it works reliably on multiple devices?

I have never been able to reproduce this issue. I have been able to reproduce #8444 in the past on my device, but I'm no longer able to. There is a potentially related bug in WebKit that has been causing other issues in this SDK- and it's pretty unreliable to reproduce, so maybe all of these SW event listener bugs are all being caused by this WebKit bug. https://bugs.webkit.org/show_bug.cgi?id=268797

@dlarocque
Copy link
Contributor

This has been added to a list of known issues with FCM in iOS PWAs caused by WebKit bugs in our Wiki: https://github.com/firebase/firebase-js-sdk/wiki/Known-Issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests