Gregion
Gregion

Reputation: 307

getting current and previous version number on Google Chrome Extension

I would like to compare the version number while I'm updating my Chrome Extension.

The reason is that there were a few structural changes, and I don't want my users (who already have my module) to add their details again.

I know that I can get version number of the currently running module by this line:

chrome.runtime.getManifest().version

My question is, while I'm updating, how can I compare the versions, or should I look at the issue from another angle?

Upvotes: 2

Views: 1012

Answers (1)

Xan
Xan

Reputation: 77523

The API that gets invoked on upgrade is chrome.runtime.onInstalled.

chrome.runtime.onInstalled.addListener(details => {
  if (details.reason === "update") {
    let newVersion = chrome.runtime.getManifest().version;
    console.log(`Updated from ${details.previousVersion} to ${newVersion}`);
  }
});

You could make your logic dependent on that, but it's fragile. Your storage schema isn't likely to change every version, and you need to account for users that don't do every single upgrade but jump versions (e.g. a machine was offline for a long time). Also, there are no built-in functions to compare version strings.

It's much better to store the version of your storage schema with the data itself, and trigger data migration from onInstalled.

var defaults = {
  someData: "reasonableDefault",
  /* ... */
  storageSchema: 5 // Increment this when data format changes
};

chrome.runtime.onInstalled.addListener(details => {
  if (details.reason === "update") {
    migrateData(doSomeInitialization);
  }
});

function migrateData(callback) {
  // This pulls stored values, falling back to defaults, if none
  chrome.storage.local.get(defaults, data => {
    let migrated = false;
    while (!migrated) {
      switch (data.storageSchema) {
        case 1:
          /* modify data to migrate from 1 to 2 */
          data.storageSchema = 2;
          break;
        /* ... */
        case 4:
          /* modify data to migrate from 4 to 5 */
          data.storageSchema = 5;
          break;
        case defaults.storageSchema: // Expected; we're done migrating
          migrated = true;
          break;
        default:
          throw new Error(`Unrecognized storage schema ${data.storageSchema}!`);
      }
    }
    chrome.storage.local.set(data, callback);
  });
}

Note that you will need some special logic for the case storageSchema was not used in an older version; otherwise, this code will supply the default value (as it's not in storage) and no migration will take place. So it's best to implement this before your first version goes public.

One thing to note is that Firefox WebExtensions don't support onInstalled yet (as of 2016-11-01) (Edit: RESOLVED FIXED in FF 52), but this function is safe to run on every extension start. onInstalled is just an optimization.

Upvotes: 6

Related Questions