I’ve helped to build a Firefox add-on called NAMFox over the past couple of years to help refine my skills with JavaScript and provide an avenue for more technical challenges. (Of course, I also like to provide value to customers, but that’s not the focus of this blog entry.) For add-on developers, AMO (https://addons.mozilla.org/) is THE site to use to host your add-on and put your work out there for other people to use. Of course, you can always host the add-on on your own server, but if you want integration with Firefox’s add-on searching (see below) or an easy way to manage automatic updates, then you’ll use AMO.
The Situation
In early 2008 I wanted to upload NAMFox onto AMO for the reasons mentioned above, and because the server it was already hosted on wasn’t very reliable. I set up a new account and went through the process to upload my add-on, when I encountered an error saying that I didn’t have permission to upload the add-on.* At the time I thought it was because the ID of my extension (superfastoz@neoseeker.com) didn’t match the email I registered with. (This was not the case; read further….) I gave up on trying to host it at AMO and continued using the same server the product had always used.
…Until a year later, when after some significant code rewrites I decided to try my luck again with AMO. I got the same error message and decided to investigate further. This time I discovered that it was actually because an add-on with the same ID already existed on AMO. I certainly didn’t remember uploading it before, and the previous project owner professed that he didn’t upload it on AMO either. I began writing a piece of software to download all the add-ons on AMO and check their IDs for conflicts, but I figured it would be a much more efficient use of my time to enlist some at Mozilla for help.
Enter Nick Nguyen, who helped me figure out that another user had uploaded an add-on with the same ID as mine. I was a bit disappointed; then I figured out that someone had taken NAMFox back in 2007, amended it to work with GameFAQs instead of Neoseeker, and then uploaded it to AMO with the same ID. I was flabbergasted. I had wasted so many hours trying to get NAMFox onto AMO, only to find this. Unfortunately all Nick and I could do was to email the original developer of that account to see if he would be willing to relinquish ownership of the project. Unfortunately I can’t just take it over, even though there is currently no download on the page, nor have there ever been (0 total downloads since 2007). If we didn’t hear back from the developer in a couple of months, I could perhaps take over the project then.
Well…
- We haven’t heard back from the developer, and it’s been about two weeks now.
- A couple of months is such a long period to go without a release or an update, especially since the add-on enhances a web site which is prone to change (and break NAMFox) without notice.
There was another alternative—I should change the ID of my add-on. Then I could easily upload it to AMO for people to use. There are a couple of problems with this:
- Firefox treats two different add-on files as the same add-on if they have the same ID and as two separate add-ons if they have different IDs. This means that if anyone who had the old NAMFox installed downloaded the new version with a different ID, their Firefox would have two instances of the add-on running, the old one and the new one.
- The same problem occurs with automatic updates. I can tell Firefox to download this updated NAMFox with a new ID, but now the customers that download the updates will have two instances of the add-on running.
In theory there is a way around this limitation, but I haven’t tried it…
The (Tentative) Solution
DISCLAIMER: I have not used the following techniques/code when releasing my add-on into the wild, so you should be careful if you’re going to adopt it.
UPDATE: Don’t try this! My Findings
The great thing about Firefox is that you can control just about every part of the browser, including the add-ons that the users have installed. If you’re like me, you’re probably thinking you can use this to get around the two limitations I listed above. In fact, I believe we can.
We’ve already identified the two scenarios that users can get your add-on with a new ID: through a direct download and through automatic updates.
If a user doesn’t have your add-on installed already, then we can agree that there is no problem.
If a user does have your old add-on installed already, then the new add-on must recognize this and uninstall it. This action is required regardless of whether the user used automatic updates to install the new add-on.
Turns out this is actually quite simple and only requires a few lines of code:
var oldId = "superfastoz@neoseeker.com";
var extensionManager = Components.classes["@mozilla.org/extensions/manager;1"].
getService(Components.interfaces.nsIExtensionManager);
var oldAddon = extensionManager.getItemForID(oldId);
if (oldAddon) {
extensionManager.uninstallItem(oldId);
var nsIAppStartup = Components.interfaces.nsIAppStartup;
var appManager = Components.classes["@mozilla.org/toolkit/app-startup;1"].
getService(nsIAppStartup);
appManager.quit(nsIAppStartup.eForceQuit | nsIAppStartup.eRestart);
}
This code exists in the new add-on; for me it runs in an event listener for the window’s load event. It tries to find the old add-on with a certain ID. If it exists, it’s uninstalled and Firefox is restarted to commit the change. When Firefox restarts, only the new add-on remains.
I’m planning to try this soon. I’ll update this post with the good, the bad, and the ugly after I do.
*The AMO team did a great job of cleaning this error message up. You’ll now see this message, which is much clearer.
