Skip to content
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

Make it possible to pass configurations options to the service worker from the main thread #6949

Open
TomasHubelbauer opened this issue Jan 16, 2023 · 13 comments

Comments

@TomasHubelbauer
Copy link

Hi, I am following the documentation on how to use the Firebase JavaScript SDK, specifically I am interested in FCM:
https://firebase.google.com/docs/cloud-messaging/js/receive#setting_notification_options_in_the_service_worker

The documentation states that alongside the JS SDK itself, I have to add a SW file as per the link above. I did that. Now turning the sample code in the documentation into production-ready code, I am getting rid of the hardcoded configuration strings, pulling them from my app's configuration instead.

However I am running into an issue doing this for the service worker. I can't access the main thread directly from the service worker thread, so it appears my only option is to use something like MessageChannel, Broadcast or the Client API.

But I can't help but think this is a common scenario the SDK already has an answer for, or at least, should; would folks agree? Would it be possible to have the SDK ship an API method for passing configuration options to the worker and be able to pick up the payload in the worker and initialize the SDK there as well based on the passed options?

I can and will for now do this myself using Broadcast, but IMO service workers are super fiddly to set up and make work right so I'd trust an SDK-provided solution over my own.

@google-oss-bot
Copy link
Contributor

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

@laurentpayot
Copy link

@TomasHubelbauer you can also transmit configuration options to the service worker via URL parameters. For instance:

  • in the main thread
const LANG = 'en'

navigator.serviceWorker.register(`/service-worker.js?lang=${LANG}`})
  • in the service worker
const LANG = new URL(location.href).searchParams.get('lang')

Hope it helps…

@TomasHubelbauer
Copy link
Author

TomasHubelbauer commented Jan 16, 2023

@laurentpayot The service worker is registered automatically by the Firebase JS SDK so there is no control over how that process is done, but this is a great tip for using service workers in general! Thank you

@DellaBitta
Copy link
Contributor

Hi @TomasHubelbauer,

did @laurentpayot answer your question or do you require more support?

Thanks!

@TomasHubelbauer
Copy link
Author

TomasHubelbauer commented May 27, 2023

@DellaBitta Sorry, but as you can read, this idea while good in general, doesn't apply to the JS SDK :D So no, it is not really applicable to this problem… This is a feature request for the JS SDK to be able to pass it the configuration though its API without having to whip up stuff for that as its consumer.

@DellaBitta
Copy link
Contributor

Ok, great, thanks for the quick response!

@TomasHubelbauer
Copy link
Author

My pleasure! Thanks for considering this issue for triage 🤘

@laurentpayot
Copy link

@TomasHubelbauer also note that you can communicate between your main thread and workers with BroadcastChannel (simple way) or MessageChannel (more complex but safer as it queues unread messages).

@TomasHubelbauer
Copy link
Author

@laurentpayot I know, I have noted that in the last paragraph of my original comment and I have indeed ended up using that option (BroadcastChannel) for now, but IMO this should be a feature of the library because it seems desirable that out of the box the service worker would have access to the configuration options since you need them to set up the service worker using initializeApp

Or maybe I am missing a scenario where this isn't needed and I am doing something more niche than I realized I was? I don't have a lot of experience with Firebase.

But in my case I am using the JS SDK to set up background notifications in Firebase Messaging and for that both the main thread and the worker thread need to call initializeApp in order to then initialize Firebase Messaging.

@TomasHubelbauer
Copy link
Author

TomasHubelbauer commented May 30, 2023

BTW I wasn't aware of the difference in queuing unread message behavior between the two options, thanks for clarifying it. I think I should probably switch to MessageChannel. All the more reason to have this out of the box IMO because fiddly stuff like this that needs to be set up every time seems like a prime candidate for factoring into the SDK.

@zwu52
Copy link
Member

zwu52 commented Jun 27, 2023

Thank you for your feedback, @TomasHubelbauer. I agree that facilitating communication between the service worker and the main thread through a well-designed API would be beneficial. The question at hand is whether the responsibility of handling this communication should lie within the Firebase Cloud Messaging (FCM) SDK itself.

To better understand your needs and requirements, it would be helpful if you could provide concrete use cases where you believe the FCM SDK should support and integrate this functionality.

@TomasHubelbauer
Copy link
Author

@zwu52 Absolutely!

Our use-case is pretty simple and I believe should be rather typical for anyone using the FB JS SDK for FCM? But I could be wrong.

Anyway, in our case, we are using the SDK to receive FCM messages in the web app but also in the service worker in case the web app's tab is closed so that the messages still arrive and are displayed as web push notifications. I think anyone displaying push notifications via FCM will have either this setup or just the main script in case they don't need background push notifications (and hence they will also not need the service worker and this communication channel between the two).

In case you do need it though, you need to find a way to pass data to the service worker so that the FB JS SDK can be initialized there with all the keys, secrets etc. These are the same as in the main thread and while most modern web stacks allow you to access and bake in environment variables and .env files into your main bundle, since the service worker script is not a part of the build process (usually at least I would guess) you don't really have any tooling supporting you in getting the configuration options into it.

What you're left with is the need to pass data to the service worker when your app starts up so it can also start up and setup the FB JS SDK and the FCM (messaging) feature specifically.

I don't think I've missed an existing way to do this and I've argued the reasons why I think this belongs to the JS SDK library and should not be left to the users (long story short, it is not completely trivial to set up and you need to make a choice on what communication method to use which most web devs wouldn't be familiar with so the SDK would be leaving a critical bit out and not pushing the users to the pit of success very much at all).

Let me know if you want me to expand on any of my points!

@shreyansh-casehippo
Copy link

Facing exact same issue !
Is there a way to pass a service worker registration to the Firebase SDK ?
So far I have been able to manually register a service worker for my site and established communication with my client code using Messages.

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

8 participants