firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.75k stars 872 forks source link

Feature Requests: FCM for safari 16 #6620

Open Abhishek2250 opened 1 year ago

Abhishek2250 commented 1 year ago

As Safari 16 has now Push APIs support. Will FCM work for Safari 16?

Thanks

google-oss-bot commented 1 year ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

vjekooo commented 1 year ago

isSupported function returns true for Safari 16. Does that mean that FCM supports Safari or that Safari just supports all required browser APIs for web push?

sman591 commented 1 year ago

The FCM quick start app runs background notifications successfully for me on Safari 16.2 with macOS Ventura. macOS 13 Ventura (released Oct 2022) is the minimum requirement according to Apple's documentation

andreififiita commented 1 year ago

I tried firebase messaging v9.16.0 in my app and it seems to work in background (when delivered by the service worker) but in foreground only receives notifications 3 times (messaging.onMessage handler).

fred-boink commented 1 year ago

The FCM quick start app runs background notifications successfully for me on Safari 16.2 with macOS Ventura. macOS 13 Ventura (released Oct 2022) is the minimum requirement according to Apple's documentation

I just tried on Safari tech preview 16.4 and I get this error, what version of firebase SDK you running? getFCMToken error AbortError: Couldn't decode message

EDIT: It worked in 16.3 non preview.!

fred-boink commented 1 year ago

Unfortunately it does not work on iOS 16.4 beta

Unhandled Promise Rejection: FirebaseError: Messaging: This browser doesn't support the API's required to use the Firebase SDK. (messaging/unsupported-browser).

andreififiita commented 1 year ago

Unfortunately it does not work on iOS 16.4 beta

Unhandled Promise Rejection: FirebaseError: Messaging: This browser doesn't support the API's required to use the Firebase SDK. (messaging/unsupported-browser).

What firebase version are you using? (i assume frontend and service worker would have the same version)

fred-boink commented 1 year ago

Hi @andreififiita ,

both are running the latest (9.18.0)

mavramopoulos commented 1 year ago

hello, quick question, i am using a java backend with java 7 (unfortunately) so I have the java sdk ver 8.2.0 and for the service worker I am running 9.16.0 compat version, on chrome it works fine but in Safari I don't receive any notifications. Token registration and everything else works fine. Is it a version problem? (Can't go to java 8)

andreififiita commented 1 year ago

I managed to test firebase on iOS 16.4 and successfully receive notifications, but i do have a problem when application is in foreground: when the user is using the app (in focus), the notifications are received only 3 times (which come from data firebase messages). The notifications are displayed in the app's UI (for example the user is using a chat view to talk with another user, i do not display the notification in OS bar). This doesn't happen if the app is in background, when the notifications are delivered to the OS notification bar. But every time i tested on foreground, it fails receiving notifications more than 3 times. Also, if i call method to getToken() after this, firebase returns a new token (seems like the previous one is being invalidated). I have the same behavior on Safari on macos 13.3 Ventura. I am using 9.16.0 compat version (but i assume, using modular or compat versions shouldn’t have any behavioural differences, right?)

EDIT: on Chrome and Firefox (MacOS) everything works fine, no issues there.

mavramopoulos commented 1 year ago

@andreififiita did you change anything when you tried safari? Firebase on chrome with compat works for me. Safari background or foreground won't work whatever I do, network shows no notification.

mavramopoulos commented 1 year ago

i fixed it, it was a stupid bug in my code, the 3 notifications problem occurs to me too, the reason it happens to you @andreififiita is because for some arbitrary reason the token resets after 3 notifications, I noticed it because when I refreshed a new token was created.

andreififiita commented 1 year ago

i fixed it, it was a stupid bug in my code, the 3 notifications problem occurs to me too, the reason it happens to you @andreififiita is because for some arbitrary reason the token resets after 3 notifications, I noticed it because when I refreshed a new token was created.

Sorry, i forgot to explicitly mention: on Chrome and Firefox (MacOS) everything works fine, no issues there.

But did you manage to find a solution or workaround for why the foreground notifications only come 3 times and then it stops? (invalidated firebase token it seems)

mavramopoulos commented 1 year ago

Probably Safari deletes the token because it considers it spam?

utkarsh-globant commented 1 year ago

I managed to test firebase on iOS 16.4 and successfully receive notifications, but i do have a problem when application is in foreground: when the user is using the app (in focus), the notifications are received only 3 times (which come from data firebase messages). The notifications are displayed in the app's UI (for example the user is using a chat view to talk with another user, i do not display the notification in OS bar). This doesn't happen if the app is in background, when the notifications are delivered to the OS notification bar. But every time i tested on foreground, it fails receiving notifications more than 3 times. Also, if i call method to getToken() after this, firebase returns a new token (seems like the previous one is being invalidated). I have the same behavior on Safari on macos 13.3 Ventura. I am using 9.16.0 compat version (but i assume, using modular or compat versions shouldn’t have any behavioural differences, right?)

EDIT: on Chrome and Firefox (MacOS) everything works fine, no issues there.

@andreififiita : I am also having the same issue, on chrome and mozilla firefox it works perfectly, but on safari it just receives three notifications and then stop. What I have found is, if we are not able to publish notification to the notification center, safari revokes the token and we have to follow the workflow again for getting the new token. If you watch this video (last 5-10 mins), they have explicitly mentioned that after 3 notifications they will revoke the token if notification is not published to notification center.

Video

My point is as we are using FCM (onMessage handler) and generating the notifications using the new Notification() constructor, it should go to the notification center.

What I have observed and I did get more then 3 notifications is(background use case) : if we do not do any handling for the background message in service worker file, and just service worker do the work, we get the notifications without any issue.

But for foreground(when tab is active) we have to do(onMessage handler), otherwise no message will be shown. I am working on it, will update you, if got any resolution.

andreififiita commented 1 year ago

I managed to test firebase on iOS 16.4 and successfully receive notifications, but i do have a problem when application is in foreground: when the user is using the app (in focus), the notifications are received only 3 times (which come from data firebase messages). The notifications are displayed in the app's UI (for example the user is using a chat view to talk with another user, i do not display the notification in OS bar). This doesn't happen if the app is in background, when the notifications are delivered to the OS notification bar. But every time i tested on foreground, it fails receiving notifications more than 3 times. Also, if i call method to getToken() after this, firebase returns a new token (seems like the previous one is being invalidated). I have the same behavior on Safari on macos 13.3 Ventura. I am using 9.16.0 compat version (but i assume, using modular or compat versions shouldn’t have any behavioural differences, right?) EDIT: on Chrome and Firefox (MacOS) everything works fine, no issues there.

@andreififiita : I am also having the same issue, on chrome and mozilla firefox it works perfectly, but on safari it just receives three notifications and then stop. What I have found is, if we are not able to publish notification to the notification center, safari revokes the token and we have to follow the workflow again for getting the new token. If you watch this video (last 5-10 mins), they have explicitly mentioned that after 3 notifications they will revoke the token if notification is not published to notification center.

Video

My point is as we are using FCM (onMessage handler) and generating the notifications using the new Notification() constructor, it should go to the notification center.

What I have observed and I did get more then 3 notifications is(background use case) : if we do not do any handling for the background message in service worker file, and just service worker do the work, we get the notifications without any issue.

But for foreground(when tab is active) we have to do(onMessage handler), otherwise no message will be shown. I am working on it, will update you, if got any resolution.

Hi, i also tried creating "new Notification()" in the foreground onMessage() handler but it still failed. I believe i also tried sending a postMessage to the service worker (last test a few months ago), and still failed. So i am am not sure where exactly safari "counts 3 times". Also, from what i know, the service worker's messaging.onBackgroundMessage() won't be executed if the app is in foreground. Maybe is there a way to go around this, at least for the time being?

utkarsh-globant commented 1 year ago

I managed to test firebase on iOS 16.4 and successfully receive notifications, but i do have a problem when application is in foreground: when the user is using the app (in focus), the notifications are received only 3 times (which come from data firebase messages). The notifications are displayed in the app's UI (for example the user is using a chat view to talk with another user, i do not display the notification in OS bar). This doesn't happen if the app is in background, when the notifications are delivered to the OS notification bar. But every time i tested on foreground, it fails receiving notifications more than 3 times. Also, if i call method to getToken() after this, firebase returns a new token (seems like the previous one is being invalidated). I have the same behavior on Safari on macos 13.3 Ventura. I am using 9.16.0 compat version (but i assume, using modular or compat versions shouldn’t have any behavioural differences, right?) EDIT: on Chrome and Firefox (MacOS) everything works fine, no issues there.

@andreififiita : I am also having the same issue, on chrome and mozilla firefox it works perfectly, but on safari it just receives three notifications and then stop. What I have found is, if we are not able to publish notification to the notification center, safari revokes the token and we have to follow the workflow again for getting the new token. If you watch this video (last 5-10 mins), they have explicitly mentioned that after 3 notifications they will revoke the token if notification is not published to notification center. Video My point is as we are using FCM (onMessage handler) and generating the notifications using the new Notification() constructor, it should go to the notification center. What I have observed and I did get more then 3 notifications is(background use case) : if we do not do any handling for the background message in service worker file, and just service worker do the work, we get the notifications without any issue. But for foreground(when tab is active) we have to do(onMessage handler), otherwise no message will be shown. I am working on it, will update you, if got any resolution.

Hi, i also tried creating "new Notification()" in the foreground onMessage() handler but it still failed. I believe i also tried sending a postMessage to the service worker (last test a few months ago), and still failed. So i am am not sure where exactly safari "counts 3 times". Also, from what i know, the service worker's messaging.onBackgroundMessage() won't be executed if the app is in foreground. Maybe is there a way to go around this, at least for the time being?

Hello @andreififiita : With some work around, I am able to get the notifications on safari for both foreground and background message.

Couple of observations that I have found :

  1. If we ourselves handle the events like (onMessage & onBackgroundMessage), and then generate the notification using the new Notification() constructor, safari thinks that the notification is not delivered/registered to the notification center, most like a local notification. (To verify this what I have done is I have removed any handling for background message in service worker, and let service worker publish the notifications, and it was able to publish the notifications without any issue(atleast 10 I have tested, so it would likely to work).

  2. Firebase internal Service worker listener file, handles the foreground and background notification differently, for foreground they use the client.postMessage() method to publish the event, and then on our side we handle it on the "OnMessage" listener, and for background message they directly use the service worker registration -> show notification method, which directly publish to the notification center.

So, my guess is safari think that when we use n = new Notification(in case of client.postMessage() or onMessage), we are not directly delivering it to the notification center. I have also tried with service worker registration -> show notification method in the onMessage call, it didn't work.

Final Workaround :

  1. Remove any handling on "onMessage or onbackgroundMessage event", as it is not going to triggered with my approach.
  2. In the service worker file, add a eventlistener on the push, event and do whatever parsing we need to do their, and generate the notification using self.registration.showNotification().
  3. It will handle both foreground and background message.
  4. The very first line of push event listener should be "event.stopImmediatePropagation();" So that it should not invoke any firebase service listener handling.

Sample code in service worker : `self.addEventListener('push', function(event) { event.stopImmediatePropagation(); console.log('Received a push message', event);

var title = 'Yay a message.'; var body = 'We have received a push message.'; var tag = 'simple-push-demo-notification-tag'; event.waitUntil( self.registration.showNotification(title,{body: body,tag: tag}) );}); `

andreififiita commented 1 year ago

I was thinking to bypass the fcm service worker handling as well, but i didn't know i needed event.stopImmediatePropagation(). Thanks for the this info. Also i believe this has serious architectural implications, and it will create a huge mess. Even so, even with this workaround, this seems to be disrupting the actual purpose of the push messages. For example, imagine talking with someone in a built-in chat (in your app) and while texting back and forth with another person (with the chat view open), you also receive a flood of notifications in the OS notification bar / UI. This would have a big impact on the user's experience and he might consider it spam/flood. So this means we would have something technically working, but not completely functional from a UX/UI point of view. Please let me know if i am missing something here.

andreififiita commented 1 year ago

And also, i can't seem to find the FCM data in the push event. the "event.data" field seems to be empty.

EDIT: In the meantime I found in the FCM .ts code that i need to call event.data.json() to get the data (i was just inspecting the event.data field and couldn't find anything). Maybe this information is useful for others as well.

lincolnthree commented 1 year ago

Does anyone have a full/working example of what they needed to do to get this working? Any official response from Firebase yet?

utkarsh-globant commented 1 year ago

Does anyone have a full/working example of what they needed to do to get this working? Any official response from Firebase yet?

@lincolnthree : For safari, they might have to handle the foreground message differently, currently for foreground message handling, they use the client(browser) postMessage to send a message to the client, and in client side code, the developer handle it through listening on the "onMessage" hook, and then uses the browser notification API to generate the notification.. So, I guess safari doesn't treat it as a notification delivered to the notification center, because of which it revokes the token after 3 messages.

What can be done to make that working :

  1. For SAFARI user agent, they can handle it differently, instead of sending it via a client.postMessage, they can use the same approach that they are using for background messages, or identify a way which can directly deliver a message to notification center.

  2. Or, directly ask developers to listen for "push" event in service worker file, and handle both foreground & background message their.

`self.addEventListener('push', function(event) { event.stopImmediatePropagation(); console.log('Received a push message', event);

var title = 'Yay a message.'; var body = 'We have received a push message.'; var tag = 'simple-push-demo-notification-tag'; event.waitUntil( self.registration.showNotification(title,{body: body,tag: tag}) );}); `

andreififiita commented 1 year ago

Does anyone have a full/working example of what they needed to do to get this working? Any official response from Firebase yet?

@lincolnthree : For safari, they might have to handle the foreground message differently, currently for foreground message handling, they use the client(browser) postMessage to send a message to the client, and in client side code, the developer handle it through listening on the "onMessage" hook, and then uses the browser notification API to generate the notification.. So, I guess safari doesn't treat it as a notification delivered to the notification center, because of which it revokes the token after 3 messages.

What can be done to make that working :

  1. For SAFARI user agent, they can handle it differently, instead of sending it via a client.postMessage, they can use the same approach that they are using for background messages, or identify a way which can directly deliver a message to notification center.
  2. Or, directly ask developers to listen for "push" event in service worker file, and handle both foreground & background message their.

`self.addEventListener('push', function(event) { event.stopImmediatePropagation(); console.log('Received a push message', event);

var title = 'Yay a message.'; var body = 'We have received a push message.'; var tag = 'simple-push-demo-notification-tag'; event.waitUntil( self.registration.showNotification(title,{body: body,tag: tag}) );}); `

I confirm this workaround worked for me. The caveat is that, when in foreground, i am obliged to show notifications in the OS notification bar all the time, even though use has the respective UI context which contains the data from the notification (a view or an activity or a popup or a page, according to your app's business logic) right in their face.

petlys commented 1 year ago

Does anyone know if messages composed/sent using the Firebase console works with Safari and the above solution listening in on the push event? Message is received on Chrome but not on Safari.

EDIT: After testing sending a notification with the Java SDK, I get Invalid registration token when sending to a FCM token generated on Safari. For those of you who have gotten this to work, how are you generating/sending your notifications?

shawol1912 commented 12 months ago

It's working well in Safari 16.5 but a note:

The notification prompt can only be triggered by a user gesture on some browsers so you should wait for a user gesture (e.g. a click on a button) and then display the permission prompt from that event

<button @click="requestPermission()">Request Permision

requestPermission() {
  try {
    Notification.requestPermission().then((permission) => {
    if (permission === "granted") {
      console.log("Notification permission granted.");
    } else {
      console.log("Do not have permission!");
    }
  });
  } catch (e) {
    console.error("Error : ", e);
  }
}
risalfajar commented 9 months ago

They have supported it starting from Safari 16.1 Blog post

andreififiita commented 1 month ago

Hi, is anyone else experiencing issues with firebase messaging on safari 17.4? It seems firebase requests to https://fcmregistrations.googleapis.com/ are failing with 400 Bad Request. I tested so far in in Safari 17.4.1 MacOS Ventura 13.6.6 (22G630). I am using firebase 10.10.0: importScripts('https://www.gstatic.com/firebasejs/10.10.0/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/10.10.0/firebase-messaging-compat.js');

Specifically, requests to "https://fcmregistrations.googleapis.com/v1/projects/.../registrations/" seem to have missing data in the payload: {"web":{"endpoint":"","auth":"","p256dh":"","applicationPubKey": "......LMbu5N....."}}; For example, in Chrome, the endpoint, p256dh and auth properties have non-empty values (something similar to values: "https://fcm.googleapis.com/fcm/send/dKxAeok......", "BFDONgo....", and "2stao....." respectively)

Everything works well on chrome and firefox, latest versions. If someone managed to find a solution for this, please let me know.

andreififiita commented 2 weeks ago

Does anyone have a working app online where firebase messaging actually works in Safari 17.4 or 17.5 (macos or ios)?