The structure of my firebase database is as shown above. How do I ensure the urls are unique and there are no duplicates? Since, these are urls I cannot use them directly as paths, I am forced to use them as values. So solutions like this won't work.
1 Answers
If you want something to be unique within the Firebase Database, you should store it as a key. That automatically guarantees uniqueness.
As you noted, some characters cannot be used in a key. In that case you'll need to encode the value to allow it in a key and ensure you don't lose the information that makes the value unique. A very simple case of this is when someone wants to store a unique email address in the database. Since a key cannot contain .
characters, we need to encode that. A common encoding for this is to replace the .
with a ,
:
users: {
"uidOfPuf": {
name: "Frank van Puffelen",
email: "puf@firebaseui.com"
}
},
emailAddresses: {
"puf@firebaseui,com": "uidOfPuf"
}
Using a ,
is especially handy when it comes to email addresses, since an email address cannot contain a ,
.
But in general all that matters is that the encoded value is "reasonably guaranteed to be unique" and that you still store the actual value somewhere too (such as the /users/$uid/email
above).
For encoding URLs, I'd simply start with stripping all illegal characters:
var url = "http://stackoverflow.com/questions/39149216/firebase-security-rules-to-check-unique-value-of-a-child-askfirebase";
ref.child(url.replace(/[\.\/]/g, '')).set(url);
Stores:
"http:stackoverflowcomquestions39149216firebase-security-rules-to-check-unique-value-of-a-child-askfirebase": "http://stackoverflow.com/questions/39149216/firebase-security-rules-to-check-unique-value-of-a-child-askfirebase"
Update: I'm considering if using a simply hashcode for the key, which leads to more reasonably length keys:
// from http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
String.prototype.hashCode = function(){
var hash = 0;
if (this.length == 0) return hash;
for (i = 0; i < this.length; i++) {
char = this.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
var url = "http://stackoverflow.com/questions/39149216/firebase-security-rules-to-check-unique-value-of-a-child-askfirebase";
ref.child(url.hashCode()).set(url);
Leads to:
20397229: "http://stackoverflow.com/questions/39149216/firebase-security-rules-to-check-unique-value-of-a-child-askfirebase"

- 565,676
- 79
- 828
- 807
-
I was hoping for existence of a better solution because by this method, I will have to replace illegal characters, reduce the length to 768 bytes and UTF-8 encode. All this while ensuring it to be unique. Creating a hashid of some kind seems like a good option as of now. Thanks so much for the reply. – Sasank Mukkamala Aug 25 '16 at 18:18
-
You're welcome. I actually need something similar for an internal tool, so am looking for a way to get a reasonable key from a URL too. – Frank van Puffelen Aug 25 '16 at 19:45