My use case is saving a user's info. When I try to save data to Firebase using the user's email address as a key, Firebase throws the following error:
Error: Invalid key [email protected] (cannot contain
.$[]#
)
So, apparently, I cannot index user info by their email. What is the best practice to replace the .
?
I've had success changing the .
to a -
but that won't cut it since some email's have -
s in the address.
Currently, I'm using
var cleanEmail = email.replace('.','`');
but there are likely going to be conflicts down the line with this.
You can create a unique key in Firebase database using push() and then add child nodes under that key. Now next time when you come to that activity, first check if parent node exists or not. If the node exists, save parent node key and use it to save new child nodes.
In Firebase Database everything is a node, that follows the pattern key: value. Firebase Database provides us with a simple way to generate unique keys. Unique keys create new items while uploading data to a previously stored key will update.
This chat application allows users to store the basic profile and contact list. The user profile would be located on a path such as Users/$uid. User is a node in it and will have a sort of primary key associated with an ID. So, we can access each one uniquely.
In the email address, replace the dot .
with a comma ,
. This pattern is best practice.
The comma ,
is not an allowable character in email addresses but it is allowable in a Firebase key. Symmetrically, the dot .
is an allowable character in email addresses but it is not allowable in a Firebase key. So direct substitution will solve your problem. You can index email addresses without looping.
You also have another issue.
const cleanEmail = email.replace('.',','); // only replaces first dot
will only replace the first dot .
But email addresses can have multiple dots. To replace all the dots, use a regular expression.
const cleanEmail = email.replace(/\./g, ','); // replaces all dots
Or alternatively, you could also use the split()
- join()
pattern to replace all dots.
const cleanEmail = email.split('.').join(','); // also replaces all dots
We've dealt with this issue many times and while on the surface it seems like using an email as a key is a simple solution, it leads to a lot of other issues: having to clean/parse the email so it can actually be used. What if the email changes?
We have found that changing the format of how the data is stored is a better path. Suppose you just need to store one thing, the user name.
[email protected]: "John Smith"
changing it to
randomly_generated_node_name email: "[email protected]" first: "John" last: "Smith"
The randomly_generated_node_name is a string that Firebase can generate via childByAutoId, or really any type of reference that is not tied directly to the data.
This offers a lot of flexibility: you can now change the persons last name - say if they get married. Or change their email. You could add an 'index' child 0, 1, 2 etc that could be used for sorting. The data can be queried for any child data. All because the randomly_generated_node_name is a static reference to the variable child data within the node.
It also allows you to expand the data in the future without altering the existing data. Add address, favorite food, an index for sorting etc.
Edit: a Firebase query for email in ObjC:
//references all of the users ordered by email FQuery *allUsers = [myUsersRef queryOrderedByChild:@"email"]; //ref the user with this email FQuery *thisSpecificUser = [allUsers queryEqualToValue:@“[email protected]”]; //load the user with this email [thisSpecificUser observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) { //do something with this user }];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With