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/admins—Admin UID listAuth read, console write
sysconfig/providers—LLM 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;