Messages send from a background-script to a content-script are not received in the content-script in ff on android.
content script
var myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});
myPort.onMessage.addListener(function(m) {
console.log("In content script, received message from background script: "); // never fires
console.log(m.greeting); // never fires
});
document.body.addEventListener("click", function() {
myPort.postMessage({greeting: "they clicked the page!"});
});
background script
var portFromCS;
function connected(p) {
portFromCS = p;
console.log("post message from background") // ok
portFromCS.postMessage({greeting: "hi there content script!"}); // never received
portFromCS.onMessage.addListener(function(m) {
console.log("In background script, received message from content script")
console.log(m.greeting); // ok
console.log(portFromCS); // ok
console.log(portFromCS.name) // ok
portFromCS.postMessage({greeting: "hi there FROM BACKROUND script!"}); // never received
});
On firefox on windows, things work, on android, the messages to the content-script are lost in the void
Is this a known bug, and are there any known solutions?
After more research, the problem seems to be that in the background-script when a content-script connects by the listener browser.runtime.onConnect.addListener(connected), the property port.sender.tab is not set for the port argument in the callback function connected. (oddly, port.sender.url is set)
This only goes wrong for the first tab, when i open a new tab, then when a content script connects the tab object is set and the content-script receives messages from the background script. Pretty troubling that things don’t seem to work well on android, especially seeing web-extension are the only extension allowed nowadays.
As a crude, hopefully temporary, workaround i now check whether the tab is set in my connect callback. If not, i close the tab and open a new one with the same location. It’s an annoying user experience, but at least it makes messaging work.
> function connected(port) {
> var id = globalId++
> console.log(port)
> console.log("BS: connect with id: " + id)
> if(!port.sender.tab) {
> // close tab, reopen
> console.log("trouble, port not set!!!!!")
> browser.tabs.query({url: port.sender.url}).then(function(tabs) {
> console.log("AFTER TROUBLE TABS FOUNND");
> if(tabs.length >= 1) {
> var tab = tabs[0]
> browser.tabs.remove(tab.id)
> browser.tabs.create({url: port.sender.url, active: tab.active})
> }
> })
> } else {
> portsToCSs.set(id, port)
> port.onMessage.addListener(function(m) {
> console.log("BS: received message from content script: " + m)
> for (var i = listeners.length - 1; i >= 0; i--) {
> listeners[i](m, id, "")
> }
> });
> port.onDisconnect.addListener(function(p) {
> portsToCSs.delete(id)
> })
> }
> }
Now that you mention it, I actually ran into the missing port.sender.tab problem as well. I didn’t know that it only happens for some tabs. Unfortunately, everything that’s got to do with tabs is still quite unstable in Fennec.