Skip to main content

Data Layer

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

Firebase Services

Authentication

MethodProvider
Google OAuthFirebase Auth

Google OAuth is the only sign-in method. The 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
materialJobsmaterialJobs/{jobId}AI material gen jobsOwner only
sysconfig/adminsAdmin UID listAuth read, console write
sysconfig/providersLLM provider config (keys)Admin only

Planned (not live): videoJobs/{jobId} (Phase 12 video reconstruction) and renderJobs/{jobId} (Phase 16 render jobs) are planned collections — no shipped code writes them.

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

Planned (not live): the Phase 13 sensors/{sensorId}/... paths are planned for the digital-twins vertical. They were removed from database.rules.json in the 2026-07 cleanup and no shipped code writes them.

Cloud Storage

assets/{uid}/{timestamp}_{filename} — uploaded GLBs, textures

Access via signed upload/download URLs (Cloud Functions). The Phase 12 videos/{uid}/{jobId}/{filename} upload path is planned, not live.

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 (17 total)

StoreKey state
useSceneStoreobjects, objectOrder, selectedObjectId, environment, cameraTarget
useAnimationStoreclips, currentFrame, isPlaying
useProjectStoreprojectMeta, isDirty
useAuthStoreuser, tier, isLoading
useAIStoremessages, isStreaming, sessionId
useUIStoretoasts, theme
useCollabStoreremoteUsers, isConnected
useRoomStoreroomCode, isHost
useCommentStorecomments
useGenerationStorejobs (text-to-3D)
useHistoryStoreundoStack, redoStack
useUpgradeModalStorepaywall trigger, gate variant
useVersionStoreversion snapshots
useUsageStorecurrent-period usage meters
useYgmStorecatalog kinematics records
useYgmPhysicsStoreper-object physics run flag
useRosStoreROS connection + topics

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;