Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
YouTube Security VideosNutanix advances legacy and AI app management with AMD(01.10.2026 um 16:00 Uhr)
•
YouTube Security VideosPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••••
Videos & KonferenzenPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••
Sicherheitslücken (CVE)USN-8857-1: KCoreAddons vulnerability(01.10.2026 um 12:48 Uhr)
•••
YouTube Security VideosNutanix advances legacy and AI app management with AMD(01.10.2026 um 16:00 Uhr)
•
YouTube Security VideosPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••••
Videos & KonferenzenPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••
Sicherheitslücken (CVE)USN-8857-1: KCoreAddons vulnerability(01.10.2026 um 12:48 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

How I built Google Drive sync without a backend (and the 3 bugs that almost broke me)

When I started building PenPage — a privacy-first note app that stores everything in IndexedDB — I made one assumption that cost me three weeks of debugging: "G…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

When I started building PenPage — a privacy-first note app that

stores everything in IndexedDB — I made one assumption that cost me

three weeks of debugging:




"Google Drive sync will be the easy part."




It wasn't.



Here's what I learned building a sync engine entirely in the

browser, with no backend server.





## The core idea: one file to rule them all



Instead of syncing every note file individually, I built around

a single sync.json that stores all metadata:




  ppage-app/
├── sync.json ← the source of truth
├── pages/
│ └── page-*.md ← actual note content
└── images/






sync.json holds folder structure, page metadata, image metadata,

and device info — but NOT page content. On every sync:




  1. Download sync.json (or skip if modifiedTime hasn't changed)

  2. Compare local IndexedDB state vs Drive state

  3. Upload/download only what changed

  4. Upload the new sync.json



This keeps API calls to 2-3 per sync cycle instead of N×2 per file.





## Bug #1: The 404 that wasn't really a 404



Google Drive returns 404 when you try to access a folder that's

been deleted and recreated — even if a folder with the same name

exists now.



This hit me when implementing "Force Upload" (which recreates the

app folder from scratch). Device A would force upload, delete and

recreate the folder. Device B still had the old folder ID cached

— and every API call returned 404.



The fix: wrap every Drive operation in a recovery handler:




  private async withFolderRecovery<T>(
operation: () => Promise<T>
): Promise<T> {
try {
return await operation()
} catch (error) {
if (error.message.includes('404')) {
await this.reinitialize() // re-fetch all folder IDs
return await operation() // retry once
}
throw error
}
}






Any 404 triggers a full folder ID refresh, then retries. Simple,

but it took me a while to realize the root cause.





## Bug #2: The silent data corruption hiding in a sentinel value



Every sync, I run a cleanup step that repairs folder parentId

values. The check looked like this:




  // Intended: fix folders with wrong parentId
if (isRootParentId(folder.parentId)) {
repairFolder(folder)
}






isRootParentId() returned true for both 'workspace' (the

actual sentinel for "orphaned folder") AND 'root' (the correct

value for top-level user folders).



Result: every sync, ALL top-level folders got their updatedAt

timestamp refreshed to Date.now(). The comparison logic saw

local as newer than Drive → uploaded everything → silently

overwrote changes from other devices.



The fix:




  // Only match the actual bad sentinel value
if (folder.parentId === 'workspace') {
repairFolder(folder)
}






One character difference. Weeks of mysterious "my changes

disappeared" reports.






## Bug #3: IndexedDB index queries don't match undefined



Force Download is supposed to: clear local data → import from Drive.



But after Force Download, pages appeared blank. The root cause was

a chain of four silent failures:





  1. clearAllData() queries IndexedDB by workspaceId: 'global'

  2. Old records had workspaceId: undefined (pre-migration data)

  3. IndexedDB index queries are exact match — undefined ≠ 'global'

  4. Old records survived the clear


  5. importAll() tried to create records with same IDs → store.add()
    silently fails on duplicate keys

  6. New records never written → UI shows nothing




  // ❌ Misses orphan records where workspaceId is undefined
const pages = await db.getAllPages({ workspaceId: 'global' })

// ✅ Explicit orphan cleanup
const allPages = await db.getAllPages()
const orphans = allPages.filter(p => !p.workspaceId)
await deleteAll(orphans)






Lesson: store.add() failure on duplicate keys is silent.

store.put() overwrites. Know which one you're using.






## What actually works well



Despite the bugs, the architecture held up:





  • modifiedTime as a proxy for "changed" — no polling,
    no webhooks, no server


  • Parallel uploads (5 concurrent) reduced sync time 80%
    for large note sets


  • Tombstones in sync.json for deleted pages — other devices
    learn about deletions without needing the deleted file






## Would I do it again?



Yes, but I'd budget 3× more time for edge cases. The Google Drive

API docs describe the happy path. The bugs live in:




  • Stale cached folder IDs

  • Silent IndexedDB failures

  • Sentinel value collisions in your own data model



If you're building anything with Google Drive API or browser-side

sync, happy to answer questions in the comments.



PenPage: https://penpage.com

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

Bedrohungsgraph · ATT&CK-Mapping · Exploit-Belege
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
3 Knoten · 2 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How I built Google Drive sync without a backend (and the 3 bugs that almost broke me)

Thematisch verwandte Begriffe: built, Google, Drive, sync · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag