Closer/firestore.rules

74 lines
2.8 KiB
Plaintext

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// ── Helpers ──────────────────────────────────────────────────────────────
function isSignedIn() {
return request.auth != null;
}
function isOwner(uid) {
return isSignedIn() && request.auth.uid == uid;
}
function isCouplesMember(coupleId) {
return isSignedIn()
&& request.auth.uid in
get(/databases/$(database)/documents/couples/$(coupleId)).data.userIds;
}
// ── Users ─────────────────────────────────────────────────────────────────
// Each user owns exactly their own document.
match /users/{uid} {
allow read, write: if isOwner(uid);
}
// ── Invite codes ──────────────────────────────────────────────────────────
// Any authenticated user can create or read an invite code.
// Only status + acceptor fields may be updated (no re-writing the code).
match /invites/{code} {
allow read: if isSignedIn();
allow create: if isSignedIn();
allow update: if isSignedIn()
&& resource.data.status == 'pending'
&& request.resource.data.keys().hasOnly(
['status', 'acceptorUserId', 'acceptedAt', 'coupleId']);
}
// ── Couples ───────────────────────────────────────────────────────────────
// Only the two members of a couple may read or write couple data.
match /couples/{coupleId} {
allow read, write: if isCouplesMember(coupleId);
match /sessions/{sessionId} {
allow read, write: if isCouplesMember(coupleId);
}
// Question threads live under the couple document.
match /question_threads/{threadId} {
allow read, write: if isCouplesMember(coupleId);
// Answers: each user writes their own; both members can read all answers.
match /answers/{userId} {
allow write: if isOwner(userId);
allow read: if isCouplesMember(coupleId);
}
// Discussion messages: any couple member can write and read.
match /messages/{messageId} {
allow read, write: if isCouplesMember(coupleId);
}
// Reactions: any couple member can write and read.
match /reactions/{reactionId} {
allow read, write: if isCouplesMember(coupleId);
}
}
}
}
}