How to Find, Export, and Import Obsidian IndexedDB on Mobile (Android) Using Microsoft Edge
Introduction
If you use Obsidian on Android, you may want to retrieve IndexedDB data, such as old snapshots beyond the File Recovery History Length. Android does not allow direct access to IndexedDB files, but you can still access and export them using Microsoft Edge’s Remote Debugging feature.
This tutorial will guide you through:
- Finding IndexedDB in Obsidian using Edge
- Exporting IndexedDB data
- Importing IndexedDB data back into Obsidian
Step 1: Enable Developer Mode on Android
Before accessing IndexedDB, you need to enable developer options and USB debugging on your phone:
- Open Settings on your Android device.
- Go to About phone and tap “Build number” seven times until you see “You are now a developer!”.
- Go back to Settings, find Developer Options, and enable USB Debugging.
Step 2: Connect Your Phone to a PC and Use Edge Remote Debugging
- Connect your Android device to your PC via USB.
- Open Microsoft Edge on your PC.
- In Edge’s address bar, enter:
edge://inspect/#devices
- Ensure “Discover USB devices” is enabled in Edge.
- Open Obsidian on your phone.
- Find Obsidian in the Edge inspect panel and click Inspect.
- Navigate to:
Application > Storage > IndexedDB
This allows you to browse Obsidian’s IndexedDB.
Step 3: Export IndexedDB Data
You can export IndexedDB data using the following JavaScript code. Run it in the browser’s console inside the Inspect panel:
Export IndexedDB Data to Clipboard
async function exportIndexedDB(dbName) {
return new Promise((resolve, reject) => {
var req = indexedDB.open(dbName);
req.onsuccess = function (event) {
let db = event.target.result;
if (!db.objectStoreNames || !db.objectStoreNames.length) {
reject(`❌ Error: Database "${dbName}" has no available object stores.`);
return;
}
let tx = db.transaction(db.objectStoreNames, "readonly");
let promises = [];
for (let storeName of db.objectStoreNames) {
let store = tx.objectStore(storeName);
let getAllReq = store.getAll();
let storePromise = new Promise((resolve, reject) => {
getAllReq.onsuccess = () => resolve({ [storeName]: getAllReq.result });
getAllReq.onerror = () => reject(getAllReq.error);
});
promises.push(storePromise);
}
Promise.all(promises)
.then(results => {
let exportData = Object.assign({}, ...results);
resolve(exportData);
})
.catch(reject);
};
req.onerror = () => reject(`❌ IndexedDB failed to open: " + req.error`);
});
}
// Copy JSON to clipboard
async function copyJsonToClipboard(dbName) {
try {
const data = await exportIndexedDB(dbName);
const jsonString = JSON.stringify(data, null, 2);
// Copy to clipboard
await navigator.clipboard.writeText(jsonString);
console.log(`✅ Database "${dbName}" data copied to clipboard! You can paste it into Notepad or Obsidian.`);
} catch (error) {
console.error(`⚠️ Failed to export database "${dbName}":`, error);
}
}
// Run and copy database data
const dbName = "your_database_name"; // Replace with your actual IndexedDB name
copyJsonToClipboard(dbName);
Step 4: Import IndexedDB Data
If you need to import IndexedDB data back, you can use the following code:
Import JSON Data into IndexedDB
async function importJsonToIndexedDB(dbName, jsonData) {
return new Promise((resolve, reject) => {
var req = indexedDB.open(dbName);
req.onsuccess = function (event) {
let db = event.target.result;
if (!db.objectStoreNames || !db.objectStoreNames.length) {
reject(`❌ Error: Database "${dbName}" has no available object stores.`);
return;
}
let tx = db.transaction(db.objectStoreNames, "readwrite");
let promises = [];
for (let storeName of db.objectStoreNames) {
if (!jsonData[storeName]) continue;
let store = tx.objectStore(storeName);
jsonData[storeName].forEach(record => {
let putRequest = store.put(record);
let storePromise = new Promise((resolve, reject) => {
putRequest.onsuccess = () => resolve();
putRequest.onerror = () => reject(putRequest.error);
});
promises.push(storePromise);
});
}
Promise.all(promises)
.then(() => {
console.log(`✅ Data successfully imported into "${dbName}" IndexedDB!`);
resolve();
})
.catch(reject);
};
req.onerror = () => reject(`❌ IndexedDB failed to open: " + req.error`);
});
}
// Load JSON file and import data
async function loadJsonFileAndImport(dbName, fileInput) {
const file = fileInput.files[0];
if (!file) {
console.error("❌ Please select a JSON backup file!");
return;
}
const reader = new FileReader();
reader.onload = async function (event) {
try {
const jsonData = JSON.parse(event.target.result);
await importJsonToIndexedDB(dbName, jsonData);
} catch (error) {
console.error("❌ Failed to parse JSON file:", error);
}
};
reader.onerror = () => console.error("❌ Failed to read JSON file!");
reader.readAsText(file);
}
// Create file selector
function createFileInput(dbName) {
const input = document.createElement("input");
input.type = "file";
input.accept = ".json";
input.onchange = () => loadJsonFileAndImport(dbName, input);
input.click();
}
// Run import function
function importDataToDB(dbName) {
console.log(`📂 Select a JSON backup file to import data into "${dbName}"`);
createFileInput(dbName);
}