Firefox IndexedDB";更新;每个浏览器都会重新启动并删除数据

Firefox IndexedDB";更新;每个浏览器都会重新启动并删除数据,firefox,indexeddb,firefox-addon-webextensions,Firefox,Indexeddb,Firefox Addon Webextensions,我编写了一个Firefox WebExtension,它从网站下载数据文件,并使用IndexedDB存储/更新数据。创建的.SQLite文件大小约为2GB。每当我重新启动Firefox时,扩展都会执行onupgradeneeded事件,即使我总是使用版本“1”。我在该事件中创建了数据库对象存储和索引,因此所有数据最终都会被删除 只有当我在下载或存储数据时关闭Firefox时才会发生这种情况。下次启动Firefox时,它不会执行事件(应该是这样)。然后,它将继续按照编程的方式更新数据库 我安装了S

我编写了一个Firefox WebExtension,它从网站下载数据文件,并使用IndexedDB存储/更新数据。创建的
.SQLite
文件大小约为2GB。每当我重新启动Firefox时,扩展都会执行
onupgradeneeded
事件,即使我总是使用版本“1”。我在该事件中创建了数据库对象存储和索引,因此所有数据最终都会被删除

只有当我在下载或存储数据时关闭Firefox时才会发生这种情况。下次启动Firefox时,它不会执行事件(应该是这样)。然后,它将继续按照编程的方式更新数据库

我安装了SQLite管理器扩展,希望能够识别导致数据库出现问题的原因,但对我来说什么都不明显

以下是我的背景脚本的一部分:

init().then(fetchData).then(addData).catch(dberror);

function init() {
    req = indexedDB.open("db", 1);

    req.onupgradeneeded = e => {
        var name;
        var key;

        console.log("Upgrading database...", e.oldVersion, e.newVersion);
        db = e.currentTarget.result;
        var store = db.createObjectStore("db", { keyPath: "KEY" });
        db.createObjectStore("version", { keyPath: "version" });

        for (name in indexes) {
            key = ...
            store.createIndex(name, key);
        };
    };

    return new Promise( (resolve, reject) => {
        req.onsuccess = e => {
            db = e.currentTarget.result;
            db.onerror = dberror;
            var cursor = db.transaction("MECs").objectStore("MECs").index("STATUS_DATE").openCursor(null, 'prev');
            cursor.onsuccess = e => {
                if (e.target.result) {
                    lastMod = e.target.result.key;
                    fileYear = lastMod.getFullYear();
                }
                else lastMod = new Date(startingfileYear, 0);
                resolve(lastMod);
            }
            cursor.onerror = reject;
        };
        req.onerror = e => {
            dberror(e);
            reject(e);
        }
    });
}

function fetchData(param) {
    // Get data based on the param and return it
    return fetchFile(filename);
}

function addData(data) {
    var trans = db.transaction("db", "readwrite");
    var store = trans.objectStore("db");
    var req;
    var n = 0;
    var data2 = [];
    var addPromise;

    trans.onerror = event => console.log("Error! Error! ", event.target.error);
    trans.onabort = event => console.log("Abort! Abort! ", event.target.error);

    data.forEach((row, index) => {
        //process data here
        data2 = ...
    });

    (function storeRegData(n) {
        var row = data[n];
        if (!row) return;
        req = store.put(row);
        req.onsuccess = event => {
            numUpdated++;
            storeRegData(++n);
        }
        req.onabort = event => console.log("Abort! Abort! ", event.target.error);
        req.onerror = event => console.log("Error! Error! ", event.target.error);
    })(0);   // I'm storing one row at a time because the transaction is failing when I queue too many rows.

    addPromise = fetchData(data2).then(
        response => {
            var trans2 = db.transaction("db", "readwrite");
            var store2 = trans2.objectStore("db");
            var req2;
            response.forEach(row => {
                req2 = store2.put(row);
                req2.onsuccess = event => numUpdated++;
                req2.onerror = console.log;
            });
            return new Promise((resolve, reject) => trans2.oncomplete = e => resolve(response));
        },
        console.log)
    );

    return new Promise((resolve, reject) => trans.oncomplete = e => {
        if (noMoreData)
            resolve(addPromise);
        else if (moreData)
            resolve( addPromise.then(fetchData).then(addData) );
    });
}
这是我的舱单

{
"author": "Name",
"manifest_version": 2,
"name": "Extension",
"description": "Extension",
"version": "3.0",

"applications": {
  "gecko": {
    "strict_min_version": "50.0",
    "id": "myID",
    "update_url": "https://update.me"
  }
},

"background": {
  "scripts": [
    "js/background.js"
  ]
},

"content_scripts": [
  {
    "matches": [ "https://match.me/*" ],
    "js": [
      "script.js"
    ],
    "css": [
      "style.css"
    ]
  }
],

"icons": {
  "48": "icon.png"
},

"options_ui": {
  "page": "options.html"
},

"page_action": {
  "browser_style": true,
  "default_icon": {
    "19": "icon-19.png",
    "38": "icon-38.png"
  },
  "default_title": "Extension",
  "default_popup": "popup.html"
},

"permissions": [
  "https://web.address/*",
  "downloads",
  "notifications",
  "storage",
  "tabs",
  "webRequest",
  "webNavigation"
],

"web_accessible_resources": [
  "pictures.png"
]
}
当我重新启动浏览器时,为什么Firefox认为数据库的版本为0?我可以在下载后使用存储的数据,为什么每次重新启动时都会覆盖它?我可以做一个变通方法,只在扩展安装或更新时创建存储和索引,但这并不是解决实际问题的方法

更新:我尝试了以下方法,但没有成功-

  • 存储每个数据文件后,关闭数据库并重新打开
  • 为每个数据文件创建一个新的对象存储
  • 更新2:这似乎与存储问题有关。显然,2GB是非持久性存储的存储限制。在Firefox中,您可以通过以下命令使存储持久化来绕过此问题:
    indexedDB.open(“db”,{version:1,storage:“persistent”})

    参见bugzilla报告

    不幸的是,当从后台页面运行时,请求确认的弹出窗口不会被处理,因此您永远无法确认它。据推测,当Firefox56出现时,您将能够使用“unlimitedStorage”权限,该权限将绕过确认弹出窗口,因此它应该在后台页面工作

    更新3:所以看起来限制实际上是~1.5 GB。我刚刚花了一个多星期的时间重新编码扩展,为每年的数据创建并使用不同的数据库,使每个数据库不超过150MB。当我重新启动浏览器并擦除所有数据时,仍然执行
    onupgradeneeded
    。但是,如果我将所有数据库中的数据总量限制在上述限制范围内,它就可以工作。不幸的是,我仍然在同一条船上


    没有人有任何想法吗?

    正如我在问题更新中提到的,indexedDB的“默认”存储空间似乎有~1.5GB的限制。将存储更改为“持久”将删除该限制。但是,由于持久性存储当前需要用户输入,因此必须从能够处理UI响应的窗口打开数据库

    通过使用
    browser.window.create()
    创建一个新窗口并从那里打开数据库,可以在后台脚本中完成此操作。有一些安全限制阻止内联脚本在新页面中运行,因此我必须为此链接到本地javascript文件(即
    )。我认为您也可以使用清单指令更改内容安全策略,但我没有这样做


    希望Firefox 56中支持
    无限制存储
    权限,这将删除弹出窗口,允许直接从后台脚本创建/访问持久数据库。

    正如我在问题更新中提到的,“默认值”似乎有~1.5GB的限制indexedDB的存储。将存储更改为“持久”将删除该限制。但是,由于持久存储当前需要用户输入,因此必须从可以处理UI响应的窗口打开数据库

    通过使用
    browser.window.create()(即
    。我认为您也可以使用清单指令更改内容安全策略,但我没有这样做


    希望Firefox 56中支持
    无限制存储
    权限,这将删除弹出窗口,允许直接从后台脚本创建/访问持久数据库。

    请将问题放在主题中:包括一个重复该问题的问题。对于Chrome扩展或Firefox WebExte这几乎总是意味着包括manifest.json和一些背景、内容和/或弹出脚本/HTML。寻求调试帮助的问题(“为什么这段代码没有按我想要的方式工作?”)必须包括:(1)所需的行为,(2)特定的问题或错误,以及(3)在问题本身中复制问题所需的最短代码。另请参见:,和。需要a的原因是我们希望提供帮助。如果我们不必重新创建复制问题所需的任何代码,那么提供帮助会容易得多。这是您已经拥有的代码。因此,请帮助我们帮助您并提供完整的解决方案重复问题。如果没有a,甚至开始帮助您所需的工作量也要高得多,这大大减少了愿意/能够帮助您的人数。即使我们付出了额外的努力,我们也必须猜测您的问题的重要部分。在(Ctrl-Shift-J或OSX上的Cmd-Shift-J)当您尝试安装和使用该扩展时?我同意我没有在其中输入足够的代码。从我的角度来看,没有任何其他与该问题真正相关的内容