firebase-js-sdk icon indicating copy to clipboard operation
firebase-js-sdk copied to clipboard

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

Open stefan-krajnik opened this issue 2 years ago • 30 comments

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.

https://github.com/firebase/firebase-js-sdk/assets/16229997/0ddcf4c4-c213-493f-80cb-ca72222e6af6

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

stefan-krajnik avatar May 18 '23 21:05 stefan-krajnik

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?

looptheloop88 avatar May 19 '23 15:05 looptheloop88

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.

stefan-krajnik avatar May 22 '23 19:05 stefan-krajnik

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.

looptheloop88 avatar May 23 '23 11:05 looptheloop88

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

stefan-krajnik avatar May 24 '23 18:05 stefan-krajnik

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:

  • https://taoshu.in/web/push-demo/
  • https://cleverpush.com/en/test-notifications/
  • https://docs.wonderpush.com/docs/web-push-notifications-quickstart

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: https://github.com/WebKit/WebKit/pull/11848, but it will probably take a while for this to end up in Safari.

Heerschop avatar May 29 '23 07:05 Heerschop

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.

Heerschop avatar May 29 '23 07:05 Heerschop

@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.

https://github.com/firebase/firebase-js-sdk/assets/2030591/ff965d72-90bc-4893-b1a9-ced5a0b2660b

taoso avatar May 30 '23 06:05 taoso

@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.

Heerschop avatar May 30 '23 07:05 Heerschop

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 avatar May 30 '23 18:05 jbalidiong

Hi all, just an update from our investigation with the engineers. This is more likely a Safari issue and the details from https://github.com/firebase/firebase-js-sdk/issues/7309#issuecomment-1566653392 are spot on. I'll leave this issue open for tracking until the PR is released on Safari's end.

jbalidiong avatar Jun 07 '23 10:06 jbalidiong

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?

MYKEU avatar Jul 05 '23 16:07 MYKEU

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

Sisyphusean avatar Jul 11 '23 21:07 Sisyphusean

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.

DellaBitta avatar Aug 08 '23 15:08 DellaBitta

@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?

goetzrobin avatar Oct 27 '23 17:10 goetzrobin

@goetzrobin I have rechecked, it still works.

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

taoso avatar Oct 27 '23 22:10 taoso

@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!

goetzrobin avatar Oct 28 '23 03:10 goetzrobin

@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?

ereshidov avatar Jan 23 '24 12:01 ereshidov

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

nmalzieu avatar Jan 27 '24 14:01 nmalzieu

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)

ereshidov avatar Jan 29 '24 16:01 ereshidov

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!

goetzrobin avatar Jan 29 '24 18:01 goetzrobin

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?

nmalzieu avatar Jan 30 '24 17:01 nmalzieu

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

ereshidov avatar Jan 30 '24 18:01 ereshidov

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

DoronTorangy avatar May 25 '24 19:05 DoronTorangy

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

egorlitsky avatar Jun 07 '24 16:06 egorlitsky