恐怖!Firefoxのchrome.storageのデータが消える

この記事は約3分で読めます。

Firefoxはバージョン57よりWebExtensionに対応しました。これによりChromeの拡張機能のFirefoxへの移植が容易になりました。しかし、完全な互換性がないので注意が必要です。

例えば、以下のコードをChromeとFirefoxで実行すると結果が異なります。Chromeのバージョンは 74.0.3729.131 Firefoxのバージョンは 66.04 で確認しています。

new Vue({
  data: {
    animals: {
      cat: 8,
      dog: 13,
      fish: 32
    }
  },
  created () {
    chrome.storage.local.set({animals: this.animals} , () => {
      chrome.storage.local.get('animals', (storage) => {
        console.log(storage.animals)
      })
    })
  }
})

chrome.storage.localにデータを保存して、保存したデータを読み込みconsoleに表示するコードです。

Chromeでは期待通りに保存されハッシュの animals が表示されます。しかし、Firefoxでは Object { } と空のオブジェクトが表示されてしまいます。

this.animals はただのハッシュではなく、Vue により getter/setter に変換されたオブジェクトです。Chromeはこれを chrome.storage.local.save で保存する際に自動的にハッシュに変換する(もしくはJSON.stringify/parse)ようです。ところが Firefox は変換してくれません。そのため、空のオブジェクトが保存されてしまったというわけです。

文字列や配列はそのまま保存できます

この問題を解決するには、Vueにオブジェクトに変換されたハッシュを自分で元に戻してから保存する必要があります。

const objectToHash = ((object) => {
  let hash = {}
  for (const key of Object.keys(object)) {
    hash[key] = object[key]
  }
  return hash
})

chrome.storage.local.set({animals: objectToHash(this.animals)})

このFirefoxの動作ですが、以前はChromeと同じだったと思います。おそらく、以下の変更が影響しているのでしょう。

「Firefox 66」の拡張機能は“IndexedDB”の採用でパフォーマンスアップ/「Adblock Plus」などの広告ブロッカーで効果大
 Mozillaは2月15日(米国時間)、「Firefox 66」で導入される拡張機能の改善を明らかにした。30件の問題が解決され、パフォーマンスと安定性、開発体験が向上しているという。

正常に動作していたコードがFirefoxのアップデートによってデータを破壊するコードになります。Chromeと同じコードが動くと思って、Firefoxの拡張機能を作りっぱなしにするのは良くありませんね。Firefoxの変更にも注意しないといけません。

コメント