Skip to content

Instantly share code, notes, and snippets.

@loucou
Last active July 24, 2023 14:12
Show Gist options
  • Save loucou/86147013dd56a95f994faae802d76e40 to your computer and use it in GitHub Desktop.
Save loucou/86147013dd56a95f994faae802d76e40 to your computer and use it in GitHub Desktop.
async function attendCourse(studentId, courseId) {
const attendingRef = db.doc(`students/${studentId}/attending/${courseId}`);
const attendeeRef = db.doc(`courses/${courseId}/attendees/${studentId}`);
const batch = db.batch();
batch.set(attendingRef, {});
batch.set(attendeeRef, {});
await batch.commit();
}
async function attendCourse(studentId, courseId) {
const junctionRef = db.doc(`junction_student_course/${studentId}_${courseId}`);
await junctionRef.set({ studentId, courseId });
}
async function fetchCourses(studentId) {
const courseIds = await db.collection(`students/${studentId}/attending`).get();
const courseDocs = await Promise.all(
courseIds.docs.map(doc => db.doc(`courses/${doc.id}`).get())
);
return courseDocs.filter(doc => doc.exists).map(doc => ({ id: doc.id, ...doc.data() }));
}
async function fetchCourses(studentId) {
const junctions = await db
.collection(`junction_student_course`)
.where("studentId", "==", studentId)
.get();
const courses = await Promise.all(
junctions.docs
.filter(doc => doc.exists)
.map(doc => db.doc(`courses/${doc.data().courseId}`).get())
);
return courses.filter(doc => doc.exists).map(doc => ({ id: doc.id, ...doc.data() }));
}
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /students/{studentId} {
allow read: if request.auth != null && request.auth.uid == studentId;
allow write: if false;
}
match /courses/{courseId} {
allow read: if request.auth != null && isAttending(request.auth.uid, courseId);
allow write: if false;
}
match /courses/{courseId}/attendees/{studentId} {
allow read, write: if request.auth != null && request.auth.uid == studentId;
}
match /students/{studentId}/attending/{courseId} {
allow read, write: if request.auth != null && request.auth.uid == studentId;
}
function isAttending(studentId, courseId) {
let path = /databases/$(database)/documents/courses/$(courseId)/attendees/$(studentId);
return exists(path);
}
}
}
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /junction_student_course/{junctionId} {
allow read:
if request.auth != null
&& request.auth.uid == resource.data.studentId;
allow create:
if request.auth != null
&& request.auth.uid == request.resource.data.studentId
&& junctionId == request.auth.uid + "_" + request.resource.data.courseId;
allow update:
if request.auth != null
&& request.auth.uid == request.resource.data.studentId
&& request.auth.uid == resource.data.studentId
&& junctionId == request.auth.uid + "_" + request.resource.data.courseId;
allow delete:
if request.auth != null
&& request.auth.uid == resource.data.studentId;
}
match /courses/{courseId} {
allow read: if request.auth != null && isAttending(request.auth.uid, courseId);
allow write: if false;
}
function isAttending(studentId, courseId) {
let junctionId = studentId + "_" + courseId;
let path = /databases/$(database)/documents/junction_student_course/$(junctionId);
return exists(path);
}
}
}
async function unattendCourse(studentId, courseId) {
const attendingRef = db.doc(`students/${studentId}/attending/${courseId}`);
const attendeeRef = db.doc(`courses/${courseId}/attendees/${studentId}`);
const batch = db.batch();
batch.delete(attendingRef);
batch.delete(attendeeRef);
await batch.commit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment