rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // =============================================================== // Assumed Data Model // =============================================================== // // Collection: users // Document ID: {uid} (Firebase Auth UID) // Fields: // - name: string (required, 1-100 chars) // - email: string (required, valid email format) // - phone: string (required, 1-20 chars) // - uid: string (required, matches document ID) // - createdAt: string (required, ISO 8601 format) // // Collection: subscriptions // Document ID: {uid} (Firebase Auth UID) // Fields: // - plan: string (required, enum: ['Aura Pro']) // - topUpAmount: number (required, positive) // - rechargeLevel: number (required, positive) // - uid: string (required, matches document ID) // - updatedAt: string (required, ISO 8601 format) // // =============================================================== // =============================================================== // Helper Functions // =============================================================== function isAuthenticated() { return request.auth != null; } function isOwner(userId) { return isAuthenticated() && request.auth.uid == userId; } function isValidEmail(email) { return email is string && email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"); } function isValidDateString(dateStr) { return dateStr is string && dateStr.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.*Z?$"); } function hasOnlyAllowedFields(fields) { return request.resource.data.keys().hasOnly(fields); } // Domain Validators function isValidUser(data) { return hasOnlyAllowedFields(['name', 'email', 'phone', 'uid', 'createdAt']) && data.name is string && data.name.size() > 0 && data.name.size() <= 100 && isValidEmail(data.email) && data.phone is string && data.phone.size() > 0 && data.phone.size() <= 20 && data.uid == request.auth.uid && isValidDateString(data.createdAt); } function isValidSubscription(data) { return hasOnlyAllowedFields(['plan', 'topUpAmount', 'rechargeLevel', 'uid', 'updatedAt']) && data.plan in ['Aura Pro'] && data.topUpAmount is number && data.topUpAmount > 0 && data.rechargeLevel is number && data.rechargeLevel >= 0 && data.uid == request.auth.uid && isValidDateString(data.updatedAt); } // =============================================================== // Rules // =============================================================== match /users/{uid} { allow read, write: if true; } match /subscriptions/{uid} { allow read, write: if true; } // Default deny match /{path=**} { allow read, write: if false; } } }