Reputation: 3417
I have a Firebase Realtime Database with the below structure.
I wish to fetch all "notes" a user has access to and, initially, only show titles for the notes.
notes: {
"noteId-1345" : {
"access" : {
"author": "1234567890"
"members": {
"1234567890": 0 <--- Author
"0987654321": 1 <--- Member
}
},
"data" : {
"title": "Hello",
"content": "Konichiwa!",
"comment": "123"
}
}
}
To be able to fetch all notes a user has access to I have expanded my data model by keeping an additional user_notes node in the root:
Whenever I associate a user (update of members
) with a note, I write that relation both in /notes/$noteid
and in /user_notes/$uid
.
user_notes: {
"$uid": {
"noteId-1345": true
}
}
When fetching initial data I only need the "notes" the user has access to - including titles.
(I only fetch the entire "note" if a user wants to view a complete "note")
I begin by fetching the ids for notes the user has access to and then I have to do another lookup to fetch the titles.
let titles = []
database.ref(`user_notes/${uid}`)
.on('value', (snaps) => {
snaps.forEach((snap) => {
const noteId = snap.key
database.ref(`notes/${noteId}/data/title`).on('value', (noteSnap) => {
const title = noteSnap.val()
titles.push(title)
}
})
})
Is this the most efficient approach? - It seems inefficient to do double lookups.
Should I store title, and other data needed for initial load, in the user_notes
node as well to avoid double lookups?
What is considered to be best practice in cases like this when using a NoSQL database?
Kind regards /K
Upvotes: 0
Views: 79
Reputation: 600006
What you're doing is indeed the common approach. It is not nearly as slow as you may initially think, since Firebase pipelines the requests over a single connection.
A few things to consider:
I'd typically move the members for each note under a top-level node note_members
. Separating the types of data typically makes it much easier to keep your security rules reasonable, and is documented under keep your data structure flat.
If you'd like to get rid of the lookup, you can consider storing the title of each note under each user_notes
node where you have the ID. You'd essentially replace the true
with the name:
user_notes: {
"$uid": {
"noteId-1345": "Hello"
}
}
This simplifies the lookup code (its main advantage) and makes it a bit faster.
This sort of data duplication is quite common when using Firebase and other NoSQL databases, you trade write complexity and extra data storage, for reach simplicity and scalability.
Upvotes: 1