One company workspace for every device. Invoices, purchases, payments, receipts, banks, customers, items and tax codes save automatically and appear wherever you open the updated app.
Live backup will start after cloud sync.
All devices share the same recordsNo email sign-in or device linking is needed. Open the same updated Accounts Platform page on your desktop, phone or tablet.
Workspace recovery
Saved records sync automatically across devices. If edits conflict, the current Firebase version stays active and the other version is preserved automatically. Your unfinished invoice draft stays on this device.
Firestore syncs records live. Firestore keeps the latest company JSON backup automatically, within its document size limit. Local backups remain available offline.
Cloud setup · same Firebase as Itinerary Builder
Uses the existing travelog-itinerary Firestore project directly, without Authentication or a separate Storage bucket. Invoice records use itineraryBuilder/crmState/invoiceStudio, separate from itinerary records.
If the existing itinerary rules cover all workspace subcollections, no rule change is needed. If access is denied, add this scoped rule inside the existing Firestore documents block and preserve all itinerary rules.
Like the reference app, this setup allows visitors with the app to access the shared records.
// Add inside match /databases/{database}/documents only if existing
// itinerary workspace rules do not already cover its subcollections.
match /itineraryBuilder/crmState/invoiceStudio/{recordId} {
allow read: if true;
allow create, update: if
(recordId == 'manifest' && request.resource.data.schemaVersion == 3
&& request.resource.data.settings is map && request.resource.data.revision is int)
|| (recordId == 'invoiceCounter' && request.resource.data.next is int
&& request.resource.data.next >= 18)
|| (recordId == 'backup' && request.resource.data.payload is string
&& request.resource.data.payload.size() <= 900000)
|| (request.resource.data.type in ['invoices','payments','purchases','outgoingPayments','expenses','banks','customers','taxes','catalog','purchaseCatalog','suppliers']
&& request.resource.data.data is map);
allow delete: if !(recordId in ['manifest','invoiceCounter','backup']);
}