FireStore - How to not allow creation of document if there is another document with the same value in a field [duplicate] - firebase

This question already has answers here:
Firestore unique index or unique constraint?
(5 answers)
Enforcing unique userIds in Firebase Firestore
(1 answer)
firebase rule for unique property in firestore
(2 answers)
Closed 2 years ago.
I have a Firestore document collection called registrations. Inside registrations, there are documents that contain name, phone number, and age of persons. I want to write the security rules database which allows the creation of person document if and only if another person with the same name does not exist on the database
Thanks in advance

It sounds like you want to keep your names distinct, such as with a UNIQUE constraint in SQL.
It is not possible to query specific document fields in Firestore security rules.
There are two ways to do what you want with Firestore:
use name as your document id
or create a collection /usedNames with name as document id, so that in your security rule you can test:
let name = request.resource.data.name;
return exists(/usedNames/$(name)) == false

Related

How to update a particular field in all the documents of a collection in cloud firestore? [duplicate]

This question already has answers here:
How to update a single field of all documents in firestore using flutter?
(3 answers)
Can Firestore update multiple documents matching a condition, using one query?
(8 answers)
Closed 12 months ago.
I am developing a Quiz App using flutter, firebase and cloud firestore in which users can play a quiz only once per day and the total score of all users will be reset to zero after every month. I am trying to achieve this by creating these two fields in each user document in the users collection:
isReadyToPlay: This field stores a boolean value 'true' if user didn't play the quiz, and changes to 'false' when user completes the quiz. I display a "start quiz" button if the value is true and remove it if the value is false. But I need to update this value to 'true' again, to allow the user to play the quiz the next day. So how do I update this field in all the documents from the collection?
total_score: This field stores the total score of all the quizzes a user plays. I want to reset this score to zero after every month. So again, I need to update this field in all the documents of the users collection.
I want to update the mentioned fields in all the documents at once from the admin end. If this is not possible, what could be a work around to achieve this?
You can do it like this first get all the documents as a snapshot and just update the required field of each document in the snapshot.
FirebaseFirestore.instance.collection('users').get().then((snapshot) {
for (DocumentSnapshot ds in snapshot.docs) {
ds.reference.update({
'isReadyToPlay': true, //True or false
'totalScore': 254 //Your new value
});
}
})

How to use parameters from "where" in Firestore security rules? [duplicate]

This question already has answers here:
Firebase Firestore security rule: Only allow collection group query if filtering by a specific field
(2 answers)
Firestore Security Rules: Passing a request parameter in a get() call?
(1 answer)
Can I send value with request to Firestore rules
(2 answers)
Firebase Firestore - security rule based on "where" query parameters
(1 answer)
Closed last year.
I have the following Firestore query which can be invoked by a non-Firebase user (the sessionId is just a session id - not a Firebase user id):
const q = query(collection(firestore, "apples"), where("sessionId", "==", sessionId));
I am thinking that I need a Firestore rule to prevent access to the whole apples collection. I just want the user to access the documents where the sessionId field matches the sessionId of the requester.
I tried (which does not work):
match /apples/{appleID} {
allow read: if request.resource.data.sessionId == resource.data.sessionId;
}
But if I have understood the reference correctly - request.resource is only available on write requests.
How can I solve this issue?

Firestore collection group query on document id [duplicate]

This question already has an answer here:
How to perform collection group query using document ID in Cloud Firestore
(1 answer)
Closed 1 year ago.
I am trying to run the following query:
this.db.firestore
.collectionGroup('members')
.orderBy('dateModified', 'desc')
.where(firebase.firestore.FieldPath.documentId(), '==', uid)
But I get the error:
Invalid query. When querying a collection group by
FieldPath.documentId(), the value provided must result in a valid
document path, but 'X6yL5Ko55jSMWhhoQUO91xVYdEH3' is not because it
has an odd number of segments (1).
Is the only way around this to add the document id to the document?
This is not ideal as I have a lot of existing data...
The document id is the uid of the firebase user.
As the error message says, for an index on a collection group the documentId() field values are actually stored as document paths to ensure unique lookups of those values in the index.
If you want to also query on document ID over a collection group, you will indeed have to store the ID as a field value in each document.
Also keep in mind that it is then possible to get multiple documents for the query, even though that is astronomically unlikely if you use the built-in add() operation.
Adding the uid to the document itself is the only possible way at the moment and then query on that field:
this.db.firestore
.collectionGroup('members')
.orderBy('dateModified', 'desc')
.where("uid", '==', uid)
There was a Github issue for the same and explains why that's not possible.
That's pretty much why I sometimes prefer to store a root level collection members. Each document in the collection will have contain the groupID (or whatever your parent collection is meant for). If you use userID as the key for documents in there then it goes easy.
this.db.firestore.collection("members").doc(uid)
So instead of having a path like: /groups/{groupID}/members/{memberID}, the structure will be like: /groups/{groupID} and all the members will be store in the root level collection 'members'. A document in that collection may look like:
// uid as doc key
{
groupId: "groupID",
...otherFields
}
The catch is if a member can join multiple groups you cannot use the userId as the key.

Retrive all collection except one document id Firebase [duplicate]

This question already has answers here:
Firestore: how to perform a query with inequality / not equals
(7 answers)
Closed 2 years ago.
I want to retrieve all the collections except one document id. I have following query it will get all data by validating collection field. however i want to get all data except one document.
await Firestore.instance.collection('tbl').where('id',isEqualTo:textId).getDocuments().then(
(data){
dataRowCount= data.documents.length;
}
);
Firestore doesn't offer any way to exclude documents from a query. You must can only filter for known values that you're looking for, or ranges of values. If you want to skip a document, you will have to check the query results in your code and omit the one you don't want

firebase firestore check if document with property and value exists [duplicate]

This question already has answers here:
Cloud Firestore: Enforcing Unique User Names
(8 answers)
Closed 3 years ago.
I am currently trying to verify before a user creates data in the database if the data exists. Even unter an other Document id.
Like this: User creates data, firestore rules gets all documents in collection and checks if the property name is the same as from the user provided. If yes, return unauthorized access.
At this point I have:
function checkIfCatExists(){
return get(/databases/$(database)/documents/category/$(documents)).data.name != null;
}
But this does not work. Do you guys have an idea? I could create a function for that but I want to do as much as possible with rules.
There is no way to search a collection for a specific value in security rules, as that operation wouldn't scale.
If you want to ensure unique user names, you'll have to create a collection where you use the user names as the key. You can then use the exists function in your security rules, to check if the name already exists in the collection.
Also see:
Cloud Firestore: Enforcing Unique User Names
Firestore security rule to check if character username already exists
Firestore security rules - can I query for a document with specific fields?
I want to write a rule that will don't allow add same document second time

Resources