Reputation: 6647
I am very new to NoSQL and denormalization. However, I wish to allow the actions at SignUp
within my app defined as:
I have the schema outlined as below given the quick need to check if a username/phone number is already present at user sign up, as well as the needed search and compare given if the new users contacts phone numbers are link to users already present within the app:
{
"presentUsersByPhoneNumber" : {
"1614#######" : {
"uid" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de"
},
"1614#######" : {
"uid" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded"
},
"1614#######" : {
"uid" : "1783917f-00e4-47a0-b2cd-987bdf185129"
},
"1614#######" : {
"uid" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd"
}
},
"presentUsersByUsername" : {
"ak" : {
"uid" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd"
},
"ak2" : {
"uid" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded"
},
"ak3" : {
"uid" : "1783917f-00e4-47a0-b2cd-987bdf185129"
},
"kja" : {
"uid" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de"
}
},
"users" : {
"1783917f-00e4-47a0-b2cd-987bdf185129" : {
"phoneNumber" : "614#######",
"username" : "ak3"
},
"99e4989b-a046-4c5f-9478-5ebd8bdc3ded" : {
"phoneNumber" : "1614#######",
"username" : "ak2"
},
"a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" : {
"phoneNumber" : "1614#######",
"username" : "ak1"
},
"fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" : {
"phoneNumber" : "1614#######",
"username" : "kja"
}
}
}
Is this approach going too fair in the act of denormalizaiton?
Upvotes: 1
Views: 391
Reputation: 598728
In NoSQL you should model the data for how your application needs to access it. Read this article on NoSQL data modeling for more information.
So if you need an efficient way to check whether a phone number or username is already taken, it makes sense to store mappings for those. The only thing I would probably do different there is to store them as simple types:
"phoneNumberToUid" : {
"1614#######" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de"
"1614#######" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded"
},
"usernameToUid" : {
"ak" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd"
"ak2" : "99e4989b-a046-4c5f-9478-5ebd8bdc3ded"
}
One thing I noticed in your sample data is that you have a key ak
in presentUsersByUsername
, but there is no corresponding child in users
with that name
. This typically happens because your code either aborts half-way through or because you made a mistake at some point during development.
You can prevent many of these problems by:
using multi-location updates, so that all writes are sent to Firebase as a single command
ref.update({
'/users/a96da7b1-7c4e-44bc-b82e-fc75bed52bcd/username': 'ak1',
'/usernameToUid/ak': null,
'/usernameToUid/ak1': 'a96da7b1-7c4e-44bc-b82e-fc75bed52bcd'
});
This update is safest way to change the name from the user from ak
to ak1
, wiping the old mapping and adding a new one.
using validation rules ensure that a user for each name exists
"usernameToUid": {
"$username": {
".validate": "newData.parent().parent().child(newData.va()).child('username').val() == $username"
}
}
Upvotes: 1