Unique Property in Firebase

unique property in Firebase

There is no way to ensure unique values in the Firebase Database.

But on the other hand keys are always unique within their context.

You can make use of this to model your data in such a way that it guarantees uniqueness of the property you want. Say you want the category name to be unique, store the categories under their name:

-Categories
-name
- color:
- sum:

With this structure you're guaranteed to have unique category names.

If you must store the categories under their current keys, but still want to ensure unique names. You can create a secondary index, which uses the category names as keys to ensure their uniqueness.

-Categories
-key
- color:
- name:
- sum:
-CategoryNames
-name: key

This latter approach is explained further in Kato's answer to Enforcing unique usernames with Firebase simplelogin

firebase rule for unique property in firestore

You created a document called usernames in your users collection, to track the names that are in use. But your rules are trying to find a document named after the current user's name, which will never exist in this structure.

In your current structure, you will need something like this:

allow create: if get(/databases/$(database)/documents/users/usernames).data[$(request.resource.data.username)] == request.auth.uid

So the above gets the document where you keep all the user names, and then checks if the current user name is in their for the current UID.

An alternative approach is to keep an additional colllection of all user names, and then make each document in there map a single user names to a UID. In this scenario your /usernames collection would be top-level, since it's shared between all users. The rules for this would be closer to what you currently have:

allow create: if !exists(/databases/$(database)/documents/usernames/$(request.resource.data.username))

How to enforce Uniqueness in a Property of a document field in Google Cloud Firestore

There is no way to enforce unique values of fields in Firestore. The only uniqueness you can guarantee is the document IDs within a collection, so the solution is to create a new collection where the user names are used as document IDs.

This has been discussed a few times before, so I recommend checking out:

  • Firestore security rule to check if character username already exists
  • Check a document field for a specific value in Cloud Firestore
  • I want to make unique usernames in firebase/firestore, which shows some of the relevant security rules.
  • Cloud Firestore: Enforcing Unique User Names
  • Firestore unique index or unique constraint?, a more complete write-up with code and rules samples.
  • Cloud Firestore: Enforcing Unique User Names

Firebase firestore unique values in multiple fields

What you're considering is pretty much the only way to guarantee uniqueness of a value across the database.

In a few more structured steps, it'd be:

  • Use that value as the document ID in an secondary collection. This collection purely exists to ensure uniqueness of the IDs.
  • Let the user claim it, typically by writing their UID into the document.
  • Use security rules to ensure a user can only write a document if it doesn't exist yet, and (if needed) only deleted when they own it.

The topic of unique values has been covered quite a few times before, although usually in the form of unique user names, so I recommend checking out:

  • Cloud Firestore: Enforcing Unique User Names
  • How to generate and guarantee unique values in firestore collection?
  • How to enforce Uniqueness in a Property of a document field in Google Cloud Firestore
  • Firestore unique index or unique constraint?
  • I want to make unique usernames in firebase/firestore

How to implement unique constraint on a child value of a node in Firebase?

Try the following:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("user_detail").child("1th_role");
ref.orderByChild("roll_no").equalTo(number_entered).addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
if(dataSnapshot.exist() {

Toasty.makeText(Activity_Name.this,"Number already exists",Toast.LENGTH_SHORT).show();

}
else{
//add data
}

}
@Override
public void onCancelled(DatabaseError databaseError) {

}
});

Since the student will enter the number, then do a query orderByChild("roll_no").equalTo(number_entered) that checks if the roll number that is entered already exists in the database.

Is it possible to get an array of unique values in firebase?

Nope, you cannot query a collection for unique values of a specific property of each item. You can filter on such values, so ref.child('beers').orderByChild('type').equalTo('IPA'). But that's not what you were asking. :-)

Typically if you want this type of operation in Firebase (or most other NoSQL databases), you'll keep the items (or references to the items) under a group:

{
"beer_types": {
"IPA": {
"-jwhkclclmecl": {
"name": "Two Hearted Ale",
"brewery": "Bells"
},
"-hcwiu3cp902d": {
"name": "Diabolical",
"brewery": "North Peak"
}
},
"Pale Wheat": {
"-ckqjheh292od": {
"name": "Dirty Blonde Ale",
"brewery": "Atwater"
},
}
}
}

Of course that only works if you want to only keep them in one category. If you want multiple categories, you can store references to each item under multiple categories:

{
"beers": {
"-jwhkclclmecl": {
"name": "Two Hearted Ale",
"type": "IPA",
"brewery": "Bells"
},
"-ckqjheh292od": {
"name": "Dirty Blonde Ale",
"type": "Pale Wheat",
"brewery": "Atwater"
},
"-hcwiu3cp902d": {
"name": "Diabolical",
"type": "IPA",
"brewery": "North Peak"
}
}
"beer_types": {
"IPA": {
"-jwhkclclmecl": true,
"-hcwiu3cp902d": true
},
"Pale Wheat": {
"-ckqjheh292od": true
}
},
"breweries": {
"Bells": {
"-jwhkclclmecl": true
},
"Atwater": {
"-ckqjheh292od": true
}
"North Peak": {
"-hcwiu3cp902d": true
}
}
}

Firebase security rules to check unique value of a child #AskFirebase

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"


Related Topics



Leave a reply



Submit