I have an IndexedDB database which stores a list of chats and a list of messages etc. Chats with more recent activity should be pushed onto the array first, so when creating the object store, I index the "lastMessageTime" property, which is a just a Unix timestamp:
if (!db.objectStoreNames.contains('chats')) {
const objectStore = db.createObjectStore('chats', { keyPath: 'chatID' });
objectStore.createIndex('lastMessageTime', 'lastMessageTime', { unique: false });
}
To get a list of all the chats back I created a method which opens the cursor on the index "lastMessageTime" going in the reverse direction and pushes the results onto an array:
getChats(callback) {
const chats = [];
const objectStore = this.db.transaction('chats').objectStore('chats');
const index = objectStore.index('lastMessageTime');
const request = index.openCursor(null, 'prev');
request.onsuccess = event => {
const cursor = event.target.result;
if (cursor) {
chats.push(cursor.value);
cursor.continue();
} else {
callback(chats);
}
};
}
This works perfectly on all Chromium based browsers and Firefox, but does not work on Safari (macOS Big Sur and iOS 15, iOS 14). "cursor" is always undefined and an empty array is thus always returned, despite there being entries in the object store which contain the indexed property. Am I doing something completely wrong, or is this just a bug in the IndexedDB implementation? If it's the latter, are there any workarounds that don't involve non-indexed sorting?