Is Firefox MV3 intentionally not supporting `browser.runtime.onMessage` in MV3 userScripts API? Why?

Is Firefox MV3 intentionally not supporting browser.runtime.onMessage in MV3 userScripts API? Why?

For Chrome, it supports both sending (browser.runtime.sendMessage) and receiving (browser.runtime.onMessage).

browser.runtime.onMessage can receive the browser.tabs.sendMessage from the background.

It means that it can perform the following communication between background and userScripts in the following method.

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage


So the communication would be

userScripts browser.runtime.sendMessage → background browser.runtime.onMessage browser.runtime.onUserScriptMessage

In the above, there is sender information containing the tabId, frameId, documentId, etc.

We can store the sender information and sendMessage to the userScripts later. For example, we need click a button in our popup menu, to command the userScripts to run some actions which apply only on the current window current active tab.

background browser.tabs.sendMessage(tab.id, ...) → userScripts browser.runtime.onMessage

This is what Chrome MV3 is supporting.


Why Firefox MV3 only supports sending (browser.runtime.sendMessage)?

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts#messaging

There is no clear description in MDN docs for my question. I don’t understand why MV3 userScripts API can send but not receive.

From the Messaging section of the UserScripts API docs on MDN:

However, extensions receive messages using the dedicated runtime.onUserScriptMessage and runtime.onUserScriptConnect. Dedicated handlers are used as they make it easier to identify messages from user scripts, which are a less-trusted context.

Similarly, Chrome’s Extensions API docs say:

However, they’re received using dedicated event handlers (meaning, they don’t use onMessage or onConnect). These handlers are called runtime.onUserScriptMessage and runtime.onUserScriptConnect. Dedicated handlers make it easier to identify messages from user scripts, which are a less-trusted context.

If you’re able to receive messages in a user script via runtime.onMessage in Chrome, that sounds like it may be a bug in Chrome’s implementation.

I am talking about the receiving handling in userscript, not the receiving handling in background.

dedicated runtime.onUserScriptMessage and runtime.onUserScriptConnect are provided in background side to receive the messages from userscript. This is the same for both firefox and chrome

( Sorry, i wrote it wrongly in the question )

How are you currently sending messages from the background script to userscripts in the Firefox version of your extension?
There are ways to do this without browser.runtime.onMessage handlers in the userscripts, and I’m curious which one you’re using.

In chrome, we are using chrome.tabs.sendMessage in background and chrome.runtime.onMessage in foreground.

but there is no such alternative in Firefox.

So no Firefox version for MV3.

Why Firefox makes browser.runtime.onMessage not available? Chrome has.

There are ways to do this without browser.runtime.onMessage handlers in the userscripts

Can you tell me how to receive message from background using userScript API environment?

Ahh, sorry I misunderstood what you were saying, @cyfung1031. You’re right, this is a discrepancy between what’s possible in Chrome and Firefox.

To answer the original question, yes, it looks like Firefox is intentionally not supporting browser.runtime.onMesssage. As @rob mentioned in this comment, Firefox collaboratively designed the User Scripts API with other browser vendors in the WebExtensions Community Group (WECG), and the design they created did not expose the runtime.onMesssage event to user scripts. When I spoke with a Firefox add-one engineer about this a bit ago, they confirmed that that’s the design Firefox implemented and intends to continue following.

Personally, I’m aligned with Firefox’s approach and I think Chrome’s implementation is a bug. I intend to final an issue on their repo to lay out my concerns. As I see it, the problem is that Chrome’s current implementation prevents an extension’s content scripts and background script from exchanging messages without exposing them to users scripts that have messaging enabled. This presents a material problem for extensions because user scripts are a less privileged context than content scripts and therefore shouldn’t have access to privileged communications between extension contexts. If we (the broader Web Extension community) want to allow extension contexts to send one-off messages to user scripts, I think extensions APIs should be expanded to explicitly provide that capability.

User scripts can’t receive messages directly from the background script. Instead, you’d need to set up a content script that receives messages from the background and passes them on to user scripts. If I were implementing this, I’d probably exchange messages between the content script and user script via a CustomEvent with a unique event name for each user script or for each user script world.