Skip to content

Can't use getToken() on Safari: FirebaseError: Messaging: A problem occurred while subscribing the user to FCM: Request contains an invalid argument. (messaging/token-subscribe-failed). #8356

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
andynewman10 opened this issue Jul 8, 2024 · 45 comments

Comments

@andynewman10
Copy link

andynewman10 commented Jul 8, 2024

Operating System

macOS Ventura 13.6.7, Intel processor

Browser Version

Safari 17.5 (18618)

Firebase SDK Version

10.12.3

Firebase SDK Product:

Messaging

Describe your project's tooling

Plain javascript

Describe the problem

The following exception is raised when trying to get an FCM token on Safari:

- Failed to load resource: the server responded with a status of 400 (Bad Request)
- Unhandled Promise Rejection: FirebaseError: Messaging: A problem occurred while subscribing the user to FCM: Request contains an invalid argument. (messaging/token-subscribe-failed).

Steps and code to reproduce issue

  1. Copy/paste the following code to an .html page
  2. Make sure you test this page with no risk of having the Notification permission denied: if you're using macOS Ventura, create a shortcut to the test web page on your desktop (I just use http://localhost/...), then double click this shortcut to open the web. If you're using macOS Sonoma, I believe you can use the 'Add to dock' feature to do the same thing.
  3. Test the web page: click the button.
  4. Look at the Javascript console. It will contain errors:
- Failed to load resource: the server responded with a status of 400 (Bad Request)
- Unhandled Promise Rejection: FirebaseError: Messaging: A problem occurred while subscribing the user to FCM: Request contains an invalid argument. (messaging/token-subscribe-failed).

I also tested with firebase-js-sdk 9.6.0, with identical results.

My Firebase set up does work perfectly fine on Chrome and Firefox (macOS and Windows platforms).

<html>
    <head>
        <script type="text/javascript" src="https://www.gstatic.com/firebasejs/10.12.3/firebase-app-compat.js"></script>
        <script type="text/javascript" src="https://www.gstatic.com/firebasejs/10.12.3/firebase-messaging-compat.js"></script>
        <script type="text/javascript">
            function getFCMToken() {
                const firebaseConfig = {
                    apiKey: '...',
                    appId: '...',
                    messagingSenderId: '...',
                    projectId: '...',
                    authDomain: '...',
                    storageBucket: '...',
                    measurementId: '...'
                };
                  
                const app = firebase.initializeApp(firebaseConfig);

                console.log("Calling messaging()");
                const messaging = firebase.messaging();

                messaging.getToken({vapidKey: '...'})
                    .then((currentToken) => {                
                    console.log("The token is");
                    console.log(currentToken);                    
                });
            }
        </script>
    </head>
    <body>
        <button id="getTokenBtn" onclick="getFCMToken()">getToken()</button>
    </body>
</html>

@andynewman10 andynewman10 added new A new issue that hasn't be categoirzed as question, bug or feature request question labels Jul 8, 2024
@jbalidiong jbalidiong added api: messaging needs-attention and removed new A new issue that hasn't be categoirzed as question, bug or feature request labels Jul 8, 2024
@andynewman10
Copy link
Author

Safari cannot currently use FCM messaging. The problem has been reported here #6620 (comment) as well. I reported the problem on the Flutter side here firebase/flutterfire#13048 too.

@andreififiita
Copy link

Safari cannot currently use FCM messaging. The problem has been reported here #6620 (comment) as well. I reported the problem on the Flutter side here firebase/flutterfire#13048 too.

Thank you for the feedback and the details.

@dlarocque
Copy link
Contributor

Hi @andynewman10, thanks for sharing steps to help us reproduce the issue.

The problem has been reported here #6620 (comment) as well.

Does this mean that this issue is a duplicate of #6620, or are these separate issues?

@andynewman10
Copy link
Author

andynewman10 commented Jul 9, 2024

Hi @andynewman10, thanks for sharing steps to help us reproduce the issue.

The problem has been reported here #6620 (comment) as well.

Does this mean that this issue is a duplicate of #6620, or are these separate issues?

My understanding is that #6620 seems to be about the general availability and support of Firebase Messaging on Safari, whereas the current issue is about a specific bug regarding getToken failing on macOS Safari (the Flutter counterpart, which contains additional information, is firebase/flutterfire#13048)

@andynewman10
Copy link
Author

Note that the official Firebase Messaging supported browsers page includes Safari and iOS Safari:

https://firebase.google.com/docs/web/environments-js-sdk?hl=en#browsers

Look at the 'Cloud Messaging' line.

Funnily enough, the french, spanish and german versions of the same page list Safari and iOS Safari as not supported! French version: https://firebase.google.com/docs/web/environments-js-sdk?hl=fr#browsers.

My locale is set to English so I can confirm that an English locale is not sufficient to solve the problem.

@jbalidiong
Copy link
Contributor

Hi @andynewman10, thanks for reaching out to us. I tried replicating the behavior you've encountered using the quickstart, however, getToken() is working as intended on my end. Can you try using the quickstart and verify it's reproducible in it? Also, Try following this blogpost for implementing FCM on MacOS, iOS Safari.

@andreififiita
Copy link

Hi @andynewman10, thanks for reaching out to us. I tried replicating the behavior you've encountered using the quickstart, however, getToken() is working as intended on my end. Can you try using the quickstart and verify it's reproducible in it? Also, Try following this blogpost for implementing FCM on MacOS, iOS Safari.

Hi, on which version of Safari and which macos did you try to replicate the issue we are having?

@jbalidiong
Copy link
Contributor

Hi, on which version of Safari and which macos did you try to replicate the issue we are having?

I'm using Safari 17.5 and macOS Sonoma 14.5

@andynewman10
Copy link
Author

Hi, on which version of Safari and which macos did you try to replicate the issue we are having?

I'm using Safari 17.5 and macOS Sonoma 14.5

@jbalidiong would you mind trying on macOS Ventura (13.x) and Safari 17.4/17.5? @andreififiita and I have issues on this setup, if you could try, this would be something extremely valuable for us and the macOS community in general.

Note that I am note saying the problem should be fixed if you indeed reproduce the issue on Ventura - just that we would know which customers we can target for our app right now.

@andyball89
Copy link

Hi,

Just wanted to say that we are having the exact issue @andynewman10 has described here with safari/firebase, i am surprised this is not being more widely reported unless its very specific setup/versions affected.

We are seeing this against Sonoma 14.5 | Safari 17.5, 18 beta , latest firebase.

It seems the problem may lie within the Safari implementation of Push API, the push subscribe call..

serviceWorkerRegistration.pushManager.subscribe(subscribeOptions).then

..is returning an empty subscription payload, likely as its quietly failing to create the subscription. This ties in with the missing params error from the firebase call to installs/registrations.

I have put together a very quick vanilla web push test .. Web Push Test Project. It would be interesting to see if you get the same results. (its not actually wired up to an actual service, but allows us to test the push api). Clone it, npm install and npm run dev, it should print out the localhost url to console.

The service worker is started on page load.
When you hit subscribe, it checks permissions and prompts if required.
Once user has granted, it fires the subscribe method above.

In chrome, you will see it return the endpoint, p256dh values etc (used by FB presumably under the hood for the register/install call). Now run it in safari 17.5 (or even 18 beta) and it instead returns empty values, reload the page and a subscription was not created it seems. The promise doesn't catch however, it resolves, but something must be going wrong under the hood.

Have tried switching around the SW startup logic to the user interaction event, same outcome.

Sorry i can't provide more of a solution, i am convinced it's the safari implementation of the push API that's either broke, or they have made a requirement change and it should actually be throwing a useable error.

Just to confirm, we are only seeing the issue in safari (both macos and ios). Chrome/Firefox, even on the same mac are working fine. Its not just a dev/local issue either, we are also seeing it in production.

@jbalidiong The project above should give you a very quick test of this, since we are on the same versions it would be good to note your results. It may be a bug that needs to be raised with apple.

@escapiststupor
Copy link

escapiststupor commented Jul 15, 2024

@andyball89 I am also seeing that PushSubscription.getKey() is not returning values when getting called upon its p256dh and auth values.

@jbalidiong
Copy link
Contributor

Thanks @andyball89 for a replication project. I was able to reproduce the behavior now. This will help us move forward with the investigation regarding the issue. Let me check what we can do for this issue or bring someone here that can provide more context about it. I’ll update this thread if I have any information to share.

@andreififiita
Copy link

Thanks @andyball89 for a replication project. I was able to reproduce the behavior now. This will help us move forward with the investigation regarding the issue. Let me check what we can do for this issue or bring someone here that can provide more context about it. I’ll update this thread if I have any information to share.

Hello, thank you for the reply. Can you please tell us, for the beginning, what is the difference between the success and failure tests regarding the Safari 17.4/17.5 on macos (ventura/sonoma)? We would be interested to know in which conditions (environment) you managed to run successfully the registration process in the first test (using quickstart project earlier last week, for example).

@jbalidiong
Copy link
Contributor

Hello, thank you for the reply. Can you please tell us, for the beginning, what is the difference between the success and failure tests regarding the Safari 17.4/17.5 on macos (ventura/sonoma)? We would be interested to know in which conditions (environment) you managed to run successfully the registration process in the first test (using quickstart project earlier last week, for example).

The difference is that I was able to replicate the behavior using the sample project provided by @andyball89 for testing the Push API. It is working on Chrome and other browsers but not on Safari. Also, the project doesn't contain any Firebase dependencies and we can rule out that this an SDK issue.

@hsubox76
Copy link
Contributor

hsubox76 commented Aug 2, 2024

Filling in some background info for our teams working together to figure out how to address this.

Until Safari 16, FCM was not supported in Safari. Safari introduced a push API in Safari 16 as a user brought up in this issue: #6620

This seemed to indicate we could mark Safari as an officially supported environment for FCM, which we did here by checking those cells in May 2024: https://firebase.google.com/docs/web/environments-js-sdk

However, it seems the Safari Push API still often has discrepancies with Chrome and Firefox Push APIs that mean FCM does not "just work" with it. If you look at the issue above (#6620) announcing the introduction of the Safari Push API, it's full of users saying they could not get it to work properly in Safari, with a brief break before the introduction of this new bug, which prompted a lot of new replies.

I would recommend we remove those checkmarks on the Supported Environments page indicating Safari FCM support, especially given this specific bug, until we can find a fix or workaround we can document, or at the very least, asterisk them with some footnotes.

@dlarocque
Copy link
Contributor

dlarocque commented Aug 22, 2024

@andyball89 I've tried creating a more minimal reproduction of the issue you're experiencing to confirm if it's a bug before I submit it to WebKit.

Here's what I've tested with:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <h1>Push Test</h1>
    <p id="status">Checking for service worker support...</p>

    <script>
      const statusEl = document.getElementById('status');

      const urlBase64ToUint8Array = (base64String) => {
        const padding = '='.repeat((4 - base64String.length % 4) % 4);
        const base64 = (base64String + padding)
            .replace(/-/g, '+')
            .replace(/_/g, '/');
        const rawData = window.atob(base64);
        const outputArray = new Uint8Array(rawData.length);
        for (let i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
        }
        return outputArray;
      }

      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('sw.js')
          .then(() => {
            statusEl.textContent = 'Service Worker registered!';
            return navigator.serviceWorker.ready;
          })
          .then(registration => {
            return registration.pushManager.subscribe({
              userVisibleOnly: true,
              applicationServerKey: urlBase64ToUint8Array('<VAPID_KEY>')
            });
          })
          .then(subscription => {
            statusEl.textContent = 'Subscribed to push notifications!';
            console.log('Subscription:', JSON.stringify(subscription)); 
          })
          .catch(error => {
            statusEl.textContent = 'Error subscribing to push: ' + error;
            console.error('Error subscribing to push:', error);
          });
      } else {
        statusEl.textContent = 'Service Workers not supported.';
      }
    </script>
  </body>
</html>

When I try this out, registration.pushManager.subscribe returns a valid subscription payload in both Chrome and Safari. I am on macOS Sonoma 14.6.1, and Safari version 17.6. I don't believe this would have been fixed since Safari 17.5 (your Safari version), since I don't see any mention of Push bug fixes in the 17.6 release notes.

Also, you mentioned that you're experiencing the same issue as @andynewman10 - does this mean you're able to successfully reproduce the error with the reproduction provided, or that you are just seeing the same error message in your app?

@dlarocque dlarocque added needs-info and removed bug labels Aug 22, 2024
@andyball89
Copy link

@dlarocque Thanks for the additional example. I have just tried this locally but the same issue is present..
Subscription:"{"keys":{"p256dh":"","auth":""}}"

Says it has subscribed but the returned payload is empty. Can you also supply your sw.js? Also, how were you running this, locally or hosted and with/without an ssl cert?

@andynewman10
Copy link
Author

Oops, I forgot to confirm the payload is also empty in the console. Sorry about this.

I am also getting Subscription:"{"keys":{"p256dh":"","auth":""}}", just like @andyball89.

@dlarocque
Copy link
Contributor

Oops, I forgot to confirm the payload is also empty in the console. Sorry about this.

I am also getting Subscription:"{"keys":{"p256dh":"","auth":""}}", just like @andyball89.

Okay that's good to know- this behaviour you're both seeing is causing the issue. I really wish I could find a way to reproduce this myself on my machine though- everything is working fine for me. Do you have any ideas as to what might be different between our setups? We're using the same Safari minor version- and I think it's unlikely that a recent patch to 17.6 fixed this issue.

@andynewman10
Copy link
Author

@dlarocque If I understand correctly, this issue seems to be occurring on both macOS Ventura and Sonoma, but only for some users. This is really weird, I agree. There is one difference but... where is it?

I believe I have never activated device enrollment on this machine, meaning my machine's configuration is not automatically managed by my organization (which I guess is a good thing, actually, regarding the testing being done here). Outside of this, I don't see anything specific with this machine, which I believe is very clean.

@andynewman10
Copy link
Author

Do I absolutely have to serve your page through https to test? I am currently serving it through http://localhost:45555/test.html, and I test the page by double clicking on a desktop link (again, I am not too familiar with macOS, but I believe it pre-authorizes the notification permission).

@dlarocque does it fail for you when serving from http://localhost?

@dlarocque
Copy link
Contributor

Do I absolutely have to serve your page through https to test? I am currently serving it through http://localhost:45555/test.html, and I test the page by double clicking on a desktop link (again, I am not too familiar with macOS, but I believe it pre-authorizes the notification permission).

@dlarocque does it fail for you when serving from http://localhost?

This works for me when serving from localhost, as well as from Firebase Hosting.

I wonder if for some reason, WebKit is intentionally preventing you to subscribe to push notifications. Would you be able to try to make your Safari browser as "fresh" as possible (clearing the cache, storage, etc...) and seeing if you get the same behaviour? Or alternatively try on a different device. I am not sure what exactly would cause WebKit to do this, but I have witnessed WebKit ITP cause weird issues like this before.

@andynewman10
Copy link
Author

Here's what I did:

  • Privacy > Website tracking: unchecked 'Prevent cross-site tracking'
  • Empty Caches
  • Restart Safari and try again

No change.

@andynewman10
Copy link
Author

andynewman10 commented Aug 23, 2024

  • Developer options
    • Disable site specific hacks
    • Disable local file preventions
    • Disable cross-origin restrictions
    • Enable Intelligent Tracking Prevention debug mode (haven't seen any ITP event reported, but I don't know where to look?)

Same results.

@dlarocque
Copy link
Contributor

@andyball89 @andynewman10

I was able to reproduce this issue on Safari Technology Preview 18.0, WebKit 19620.1.2!

I'll look further into this WebKit bug on Monday and share an update then.

@dlarocque
Copy link
Contributor

dlarocque commented Aug 26, 2024

@andyball89 @andynewman10 Could you please share the full Safari versions you're experiencing the bug in?

For me, I can reproduce the bug in Release 201 (Safari 18.0, WebKit 19620.1.2) (Safari Technology Preview), but the push subscribe works fine in Version 17.6 (19618.3.11.11.5)

The fact that I see the issue in WebKit 19620.1.2, but not in 19618.3.11.11.5 tells me this is a regression, but the fact that you both mentioned you're seeing this in 17.6 and 17.5 makes me wonder if that's not the case. If you're using older versions of 17.6, it may be that this was a bug that was fixed very recently, and that fix hasn't been added to the 18.0 versions yet.

@andynewman10
Copy link
Author

@dlarocque

  • I am currently using Safari 17.6 (18618.3.11.11.7, 18618) using macOS Ventura 13.6.9, Intel processor.
  • when I created the issue I was using Safari 17.5 (18618, with the remaining digits I didn't write down at the time, unfortunately) and macOS Ventura 13.6.7.

Does 18618 represent the WebKit version used by Safari?

@andynewman10
Copy link
Author

andynewman10 commented Aug 26, 2024

@dlarocque My current user agent is ending with AppleWebKit/605.1.15 ... Version/17.6 Safari/605.1.15.

@dlarocque
Copy link
Contributor

This issue does not exist on Safari 17.5 (19618.2.12.11.6) on macOS Sonoma 14.5. I also just tested on the recent version of the beta (Release 202) and the bug is still there.

@dlarocque
Copy link
Contributor

dlarocque commented Sep 6, 2024

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

@dlarocque dlarocque removed the bug label Sep 6, 2024
@andynewman10
Copy link
Author

Unfortunately, the issue persists with Safari 18.0 (18619.1.26.111.10, 18619) on macOS Ventura 13.7.

@andynewman10
Copy link
Author

Hi all,

Believe it or not, I have the same problem today on Chrome 129.0.6668.90 on my Mac. The same Mac running macOS Ventura 13.7, the same machine where Safari 17.6 and 18.0 exhibited the issue.

I had to pinch myself to verify I was not dreaming. Did it ever work on Chrome?

One thing is sure, the same code runs flawlessly on iOS, on the same machine. The same code is running fine on Chrome on my Windows machine.

Could it be that there is some system setting somewhere in macOS preventing things from running correctly and that somehow, things are not directly linked to Safari/Chrome?

@dlarocque
Copy link
Contributor

Hi all,

Believe it or not, I have the same problem today on Chrome 129.0.6668.90 on my Mac. The same Mac running macOS Ventura 13.7, the same machine where Safari 17.6 and 18.0 exhibited the issue.

I had to pinch myself to verify I was not dreaming. Did it ever work on Chrome?

One thing is sure, the same code runs flawlessly on iOS, on the same machine. The same code is running fine on Chrome on my Windows machine.

Could it be that there is some system setting somewhere in macOS preventing things from running correctly and that somehow, things are not directly linked to Safari/Chrome?

I just tested on Chrome Version 129.0.6668.60, and did not experience this issue. Since I was able to reproduce this issue on Safari 18.0, but not 17.6 on the same macOS device, I don't believe the issue is caused by a system setting.

@andynewman10
Copy link
Author

Hi all,
Believe it or not, I have the same problem today on Chrome 129.0.6668.90 on my Mac. The same Mac running macOS Ventura 13.7, the same machine where Safari 17.6 and 18.0 exhibited the issue.
I had to pinch myself to verify I was not dreaming. Did it ever work on Chrome?
One thing is sure, the same code runs flawlessly on iOS, on the same machine. The same code is running fine on Chrome on my Windows machine.
Could it be that there is some system setting somewhere in macOS preventing things from running correctly and that somehow, things are not directly linked to Safari/Chrome?

I just tested on Chrome Version 129.0.6668.60, and did not experience this issue. Since I was able to reproduce this issue on Safari 18.0, but not 17.6 on the same macOS device, I don't believe the issue is caused by a system setting.

@dlarocque You're right, it is working fine on Chrome on macOS. Weird, somehow when I posted the last message, I was getting an error similar to the one exposed in this issue. I checked and it's fine (sorry for the false alarm!). I also checked Ventura's latest Safari 18 (18619) release once again, and I confirm it fails.

@andynewman10
Copy link
Author

I checked again with Safari 18.1 (18619.2.8.111.5), released alongside Ventura 13.7.1 yesterday, to no avail.

@dlarocque sorry to bother you again with this issue - did you by chance report a bug to Apple regarding this? If you haven't I can do it (never done it before, but shouldn't be too hard I guess).

@harumhl
Copy link

harumhl commented Jan 20, 2025

Nothing much to add. Just here to say that I also started with Firebase with a hope to use Web Push notifications on Safari and it's not working (Chrome works). getToken() returns a "token" but that cannot be used to send a message to the Firebase Cloud Messaging API

Safari: Version 18.0 (20619.1.26.31.6)
Chrome: Version 132.0.6834.83 (Official Build) (arm64)
Mac: 15.0 (24A335)
Firebase: 11.2.0

@andynewman10
Copy link
Author

I installed the Ventura 13.7.3 update, released yesterday. It comes with Safari 18.3 (18620.2.4.111.8).

I believe something changed in the behavior of @andyball89 's web-push-testing project.

Now, when I run the project and test it on Safari, the text "No subscription found" remains in the page. It no longer displays an empty p256dh value. Also, there is an exception displayed in the JavaScript console:

Unhandled Promise Rejection: AbortError: Connection to web push daemon failed
  button.ts: 30

The exception happens here:

registration?.pushManager.subscribe(subscribeOptions).then(function (subscription) {
  // ...
}).catch(function (error) {
  throw error; // line 30
});

I wonder if this change of behavior shows that push subscriptions are basically dead for good on Safari 18.3 on Ventura...

@andynewman10
Copy link
Author

andynewman10 commented Jan 30, 2025

I could get a hold of a MacBook that I reinstalled from scratch, using Sonoma. I just wanted to confirm that on Safari 17.6 for Sonoma, getToken did succeed, as expected. I then upgraded to Sequoia 15.3 and Safari 18.3, and it succeeded again. So it seems that

  • pre-Sonoma Safari releases, regardless of their version number (>=17.5, and all 18.x) do not support push subscriptions.
  • Sonoma/Sequoia Safari releases do support push subscriptions. The only gitch in this reasoning is the Safari 17.5 and 18-beta versions used on Sonoma, which @andyball89 tested (see his message above). I guess Andy was not lucky and push subscriptions surprisingly failed with these specific versions of Safari on Sonoma. But I guess that was very, VERY bad luck...

@comxd
Copy link

comxd commented Feb 17, 2025

I'm just reading that on the Apple developer doc:

Ask the user for permission to send them push notifications. Provide a method for the user to grant permission with a gesture, such as clicking or tapping a button. When the user completes the gesture, call the push subscription method immediately from the gesture’s event handler code.

Someone was checked/tested if calling the getToken() method, "immediately" and inside the original "gesture’s event handler code" can help?

@escapiststupor
Copy link

I'm just reading that on the Apple developer doc:

Ask the user for permission to send them push notifications. Provide a method for the user to grant permission with a gesture, such as clicking or tapping a button. When the user completes the gesture, call the push subscription method immediately from the gesture’s event handler code.

Someone was checked/tested if calling the getToken() method, "immediately" and inside the original "gesture’s event handler code" can help?

I suppose that means make sure when getToken() is called, navigator.userActivation.isActive is true?

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