I'm developing an educational system with Class
and Student
entities. Each student can have various progress through their classes (represented by a number between 0 and 1). The task is to output Class
es ordered by progress for each Student
.
The data structure I went with is storing progress of each student on each class document:
Class1:
- progress:
- A: 0.1
- B: 0.3
Class2:
- progress:
- A: 0.9
- B: 0.5
Class3:
- progress:
- A: 0.6
- B: 0.0
And here is the Firestore query:
var orderedClasses = classesCollection.orderBy('progress.$userId')
Desired output:
Student A sees [Class1 (10%), Class3 (60%), Class2 (90%)]
Student B sees [Class3 (0%), Class1 (30%), Class2 (50%)]
And this works with the emulator data, but when running in production, Firebase is prompting me to create an index on progress.AsDASF875aSD9zxc
. This, of course, is not ideal as creating an index for each user is not feasible.
Is there an alternative data structure I should consider?
Note: ordering items on the client is not possible as there might be a lot of classes per student and pagination is being applied which I'm omitting here for brevity.
Duplicating the data is the best approach for a NoSQL database for a situation like this.
Store the data in both Classes/$class
(common/general read-only class information shared by instructors and students) and UserData/$userId/Classes/$class
(Student-specific information related to that class along with key information).
Using this structure would allow for any type of student-specific sorting (by progress, by final exam score, alphabetically, etc.) as well as making it simple to grab all classes that a given student is a member of. Additionally, the same structure can be used for instructors with tweaked information stored in each document.
Note: UserData/$userId
should only contain profile information about that user such as their username, bio and shared contact details. Sensitive private personal information (like platform roles, email addresses, phone numbers, linked authenticator details, addresses and so on) should be stored in PrivateUserData/$userId
where it is only accessible to that user and platform admins.