Skip to main content

Data Layer

Yugma is fully Firebase-native: Auth, Firestore, Realtime Database, Cloud Storage, and Cloud Functions.

Firebase Services

Authentication

MethodProvider
Email/passwordFirebase Auth
Anonymous (guest)Firebase Auth
Google OAuthFirebase Auth

Guest accounts can upgrade to email accounts without losing data. onUserCreate trigger seeds a user profile in Firestore.

Firestore Collections

CollectionPathPurposeAccess
projectsprojects/{projectId}Scene data + metadataOwner read/write
projects/*/assetsprojects/{pid}/assets/{aid}Per-project asset libraryAuthenticated
shareLinksshareLinks/{linkId}Public share link metadataPublic read, auth write
aiSessionsaiSessions/{uid}/sessions/{sid}AI chat history (Firestore copy)Owner only
aiRateLimitsaiRateLimits/{uid}Per-user rate limit countersOwner only
generationJobsgenerationJobs/{jobId}Meshy text-to-3D jobsOwner only
materialJobsmaterialJobs/{jobId}AI material gen jobsOwner only
videoJobsvideoJobs/{jobId}Phase 12 video reconstructionOwner only
renderJobsrenderJobs/{jobId}Phase 16 render jobsOwner only
sysconfig/adminsAdmin UID listAuth read, console write
sysconfig/providersLLM provider config (keys)Admin only

Realtime Database Paths

PathPurposeFrequency
collab/{sessionId}/presence/{uid}User online statusOn connect/disconnect
collab/{sessionId}/cursors/{uid}3D cursor position~30 Hz
collab/{sessionId}/deltas/{deltaId}Scene change deltasPer edit
rooms/{roomCode}Room code → session mappingOn create/join
sensors/{sensorId}/latestPhase 13 live sensor readingsVaries (MQTT bridge)
sensors/{sensorId}/history/{readingId}Phase 13 sensor historyVaries

Cloud Storage

assets/{uid}/{timestamp}_{filename} — uploaded GLBs, textures
generated/{uid}/{jobId}.glb — Meshy-generated models
videos/{uid}/{jobId}/{filename} — Phase 12 video uploads

Access via signed upload/download URLs (Cloud Functions).

AI Session Persistence

Sessions are stored in Firestore at aiSessions/{uid}/sessions/{sessionId}. Each document contains the full message array, auto-updated via setDoc with merge on each AI turn. On mount, loadLastSession queries the most recent session by updatedAt and hydrates the chat.

Client send message → AIPanel → saveAISession → Firestore (fire-and-forget)

Client mount → loadLastSession (Firestore query) → hydrateSession

Zustand Stores (14 total)

StoreKey state
useSceneStoreobjects, objectOrder, selectedObjectId, environment, cameraTarget
useAnimationStoreclips, currentFrame, isPlaying
useProjectStoreprojectMeta, isDirty
useAuthStoreuser, isLoading
useAIStoremessages, isStreaming, sessionId
useUIStoretoasts, theme
useCollabStoreremoteUsers, isConnected
useRoomStoreroomCode, isHost
useCommentStorecomments
useGenerationStorejobs (text-to-3D)
useHistoryStoreundoStack, redoStack
useTwinStorebindings, readings (Phase 13)
usePhysicsStorebodies, simulation state (Phase 15)
useVideoStorejobs (Phase 12)
useProductStorebom, enclosure, pcb, firmware (Phase 14)
useCinematicStorestoryboards, shots, renderJobs (Phase 16)

Security Rules

All Firestore rules enforce owner-only access for user-scoped data. Pattern:

allow read: if request.auth != null && resource.data.userId == request.auth.uid;
allow create: if request.auth != null && request.resource.data.userId == request.auth.uid;