Home > other >  IndexedDB breaks in Firefox after trying to save autoIncremented Blob
IndexedDB breaks in Firefox after trying to save autoIncremented Blob

Time:11-18

I am trying to implement Blob storage via IndexedDB for long Media recordings.

My code works fine in Chrome and Edge (not tested in Safari yet) - but won't do anything in Firefox. There are no errors, it just doesn't try to fulfill my requests past the initial DB Connection (which is successful). Intuitively, it seems that the processing is blocked by something. But I don't have anything in my code which would be blocking.

Simplified version of the code (without heavy logging and excessive error checks which I have added trying to debug):

const dbName = 'recording'
const storeValue = 'blobs'

let connection = null
const handler = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB

function connect() {
  return new Promise((resolve, reject) => {
    const request = handler.open(dbName)

    request.onupgradeneeded = (event) => {
      const db = event.target.result

      if (db.objectStoreNames.contains(storeValue)) {
        db.deleteObjectStore(storeValue)
      }

      db.createObjectStore(storeValue, {
        keyPath: 'id',
        autoIncrement: true,
      })
    }

    request.onerror = () => {
      reject()
    }

    request.onsuccess = () => {
      connection = request.result

      connection.onerror = () => {
        connection = null
      }

      connection.onclose = () => {
        connection = null
      }

      resolve()
    }
  })
}


async function saveChunk(chunk) {
  if (!connection) await connect()

  return new Promise((resolve, reject) => {
    const store = connection.transaction(
      storeValue,
      'readwrite'
    ).objectStore(storeValue)

    const req = store.add(chunk)

    req.onsuccess = () => {
      console.warn('DONE!') // Fires in Chrome and Edge - not in Firefox
      resolve(req.result)
    }

    req.onerror = () => {
      reject()
    }

    req.transaction.oncomplete = () => {
      console.warn('DONE!') // Fires in Chrome and Edge - not in Firefox
    }
  })
}

// ... on blob available

await saveChunk(blob)

What I tried so far:

  • close any other other browser windows, anything that could count as on "open connection" that might be blocking execution
  • refresh Firefox profile
  • let my colleague test the code on his own machine => same result

Additional information that might useful: Running in Nuxt 2.15.8 dev environment (localhost:3000). Code is used in the component as a Mixin. The project is rather large and uses a bunch of different browser APIs. There might be some kind of collision ?! This is the only place where we use IndexedDB, though, so to get to the bottom of this without any errors being thrown seems almost impossible.

Edit:

When I create a brand new Database, there is a brief window in which Transactions complete fine, but after some time has passed/something triggered, it goes back to being queued indefinitely.

I found out this morning when I had this structure:

...
clearDatabase() {
  // get the store
  const req = store.clear()

  req.transaction.oncomplete = () => console.log('all good!')
}

await this.connect()
await this.clearDatabase()

'All good' fired. But any subsequent requests were broken same as before. On page reload, even the clearDatabase request was broken again.

Something breaks with ongoing usage.

Edit2:

It's clearly connected to saving a Blob instance without an id with the autoIncrement option. Not only does it fail silently, it basically completely corrupts the DB. If I manually assign an incrementing ID to a Blob object, it works! If I leave out the id field for a regular simple object, it also works! Anyone knows about this? I feel like saving blobs is a common use-case so this should have been found already?!

CodePudding user response:

I've concluded, unless proven otherwise, that it's a Firefox bug and opened a ticket on Bugzilla.

This happens with Blobs but might also be true for other instances. If you find yourself in the same situation there is a workaround. Don't rely on autoIncrement and assign IDs manually before trying to save them to the DB.

  • Related