rules_version = '2'; // To pick the right project: `firebase projects:list`, then `firebase use ` // To deploy: `firebase deploy --only firestore:rules` service cloud.firestore { match /databases/{database}/documents { function isAdmin() { return request.auth.uid == 'igi2zGXsfxYPgB0DJTXVJVmwCOr2' // Austin || request.auth.uid == '5LZ4LgYuySdL1huCWe7bti02ghx2' // James || request.auth.uid == 'tlmGNz9kjXc2EteizMORes4qvWl2' // Stephen || request.auth.uid == 'IPTOzEqrpkWmEzh6hwvAyY9PqFb2' // Manifold } match /users/{userId} { allow read; allow update: if resource.data.id == request.auth.uid && request.resource.data.diff(resource.data).affectedKeys() .hasOnly(['bio', 'bannerUrl', 'website', 'twitterHandle', 'discordHandle', 'followedCategories']); } match /private-users/{userId} { allow read: if resource.data.id == request.auth.uid || isAdmin(); allow update: if (resource.data.id == request.auth.uid || isAdmin()) && request.resource.data.diff(resource.data).affectedKeys() .hasOnly(['apiKey']); } match /private-users/{userId}/views/{viewId} { allow create: if userId == request.auth.uid; } match /private-users/{userId}/events/{eventId} { allow create: if userId == request.auth.uid; } match /private-users/{userId}/latency/{loadTimeId} { allow create: if userId == request.auth.uid; } match /private-users/{userId}/cache/{docId} { allow read: if userId == request.auth.uid || isAdmin(); } match /contracts/{contractId} { allow read; allow update: if request.resource.data.diff(resource.data).affectedKeys() .hasOnly(['description', 'closeTime', 'tags', 'lowercaseTags']); allow update: if isAdmin(); } match /{somePath=**}/bets/{betId} { allow read; } function commentMatchesUser(userId, comment) { // it's a bad look if someone can impersonate other ids/names/avatars so check everything let user = get(/databases/$(database)/documents/users/$(userId)); return comment.userId == userId && comment.userName == user.data.name && comment.userUsername == user.data.username && comment.userAvatarUrl == user.data.avatarUrl; } match /{somePath=**}/comments/{commentId} { allow read; allow create: if request.auth != null && commentMatchesUser(request.auth.uid, request.resource.data); } match /{somePath=**}/answers/{answerId} { allow read; } match /folds/{foldId} { allow read; allow update: if request.auth.uid == resource.data.curatorId && request.resource.data.diff(resource.data).affectedKeys() .hasOnly(['name', 'about', 'tags', 'lowercaseTags']); allow delete: if request.auth.uid == resource.data.curatorId; } match /{somePath=**}/followers/{userId} { allow read; allow create, update: if request.auth.uid == userId && request.resource.data.userId == userId; allow delete: if request.auth.uid == userId; } match /txns/{txnId} { allow read; } } }