Firestore Document Rules on Field [duplicate] - firebase

This question already has answers here:
Firestore Security Rules - How can I check that a field is/isn't being modified?
(10 answers)
Closed 3 years ago.
I am looking to apply firestore rules to restrict the change (write, update) of a specific field in a document.
From what I understand in the docs you cannot apply rules on read: to document fields as documents need to be read in their entirety, however, it's not stated about writes, updates?
My structure is like the below example;
match /ads/{adDocument} {
//adDocument has a field "price" this needs to only be read not changed/updated.
};
How would I go about implementing this?

You can write a CQRS mediator for all changes, and disallow all write to the documents.
To make a change, the client can add a document to mutate the document on all mutable fields:
/PATCH_ads/{adDocument}:
- itemName: "newItemName"
The mediator should be triggered once a document is added in the PATCH_ads collection. The mediator should reject the change if receiving a command to modify price field, and commit the change if the content of the requested change is valid.

Related

How to fetch documents from a collection without certain fields from Firestore? [duplicate]

This question already has answers here:
Is there a way to select only certain fields from Firestore?
(1 answer)
How to access a specific field from Cloud FireStore Firebase in Swift
(5 answers)
How to access some fields of firestore in flutter? [duplicate]
(1 answer)
How to get value of some field in firebase firestore android?
(4 answers)
Closed 2 months ago.
I have a collection let's say "files" and a "file" document has 2 main properties (field) : name and content.
(note: I know storing files in a Firestore is not a good idea but that's just an example, let's assume the files are just text files)
When my app opens I want to be able to fetch all user's file names but not the content :
files = [{name: 'a'}, {name: 'b'}, {name: 'c'}, ...]
The reason is obvious I don't want to pull files' content unless the user explicitly ask for from the UI, minimizing the size of data being pulled from Google Cloud and reducing the cost over time.
But collection(db, 'users', user.uid, 'files') seems to return all docs data. Even worst! if one "file" document change, all the docs and their content are being pulled again from the UI onSnapshot listener...
Reading the TypeScript doc I don't see an option to do atomic selection on docs' fields. Am I missing something?

Firestore: Wherein custom object array?

im trying to make a sort of chat app with the following architecture:
Its currently working as follows: in a root doc, there is an array of chat objects. Each chat object spawns a message doc, which contains an array of message objects. Same logic for comments.
Im thinking about a function to update all posts relative to the associated user, IE if a user changes their name all associated comments will be updated. Is this possible with the WhereIn() function? Or should i edit the architecture to something more like each document being its own message/comment? Thanks!
An in clause checks if a specific field is equal to one of a set of values, which doesn't apply here.
You might be thinking of array-contains, but that wouldn't work in your current structure either. The array-contains only matches exact an item in the array if it completely/exactly matches the value in the query.
The common way to allow such a query is to add a participants array field to each document where you store the UIDs of all participants in that doc. Then you can do an array-contains query against that.

Firestore Security Rules allow specific field only [duplicate]

This question already has answers here:
How to allow only particular fields of a firestore document to be accessed publicly
(2 answers)
Can I restrict certain fields in firestore database to be only fetched by firebase admin?
(2 answers)
Closed 2 years ago.
I am trying to implement security rule to limit users to access only specific fields inside a document. My data structure goes like this:
document {
name: John,
dob: 1994,
email: john#hotmail.com
}
I want to limit the name field to read, write by owner; dob field to read by owner, create by owner; email to read by owner, update by owner
I read the documentation, and it seems that I can only control access of a specific document with security rules. It didn't mention anything to allow access to a specific field. What I should do in order to allow access to specific fields inside a document?
Security rules can't be used to limit access to individual fields in a document. If a user has direct read access to a document, they can always read every field in the document.
Your only alternatives here are:
Split the restricted fields into a document in another collection, and protect that collection differently.
Reject direct access to the collection entirely, and force users through an API endpoint that strips out the restricted fields based on the user's identity, which was passed to the endpoint.

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

Would executing the below given code will delete all the previous data?

What if some data is already there inside the users collection ?
Would doing this 👇🏻 will delete all the previous data ?
var messageRef = db.collection('users').doc(userID)
.collection('private_user_data').doc(userID);
I want to add new data inside users collection and inside that a doc with 4 fields and one more collection inside that and inside that a doc with four more fields.
The code in your question doesn't read from or write to the database in any way. It merely sets up a reference to a document in the database.
There are few ways to implement this, depending on your exact use-case:
To merge data with an existing document, use the update method.
If the document may or may not exist, you can tell Firestore to merge the new values with the existing data when you call the set method.
If you want to set some fields only if the document doesn't exist yet, and leave them unmodified if the document already exists, you will need to use a transaction. In that case you may also want to make sure your security rules reject modifications to those initial fields.
With your code you don't make any operation on your db.
If you would know use .set(someData) your document would be created with given data if there is no document with given id or the document would be overwritten with the given data if there is a document with the given id.
Please check this post from the Firebase docs for more information.
EDIT
To create a document you have to do something like this:
var messageRef = db.collection('users').doc(userID)
.collection('private_user_data').doc(userID);
messageRef.set({
field1: input1,
field2: input2,
field3: input3,
field4: input4
})
Be aware that messageRef.set() will return a promise. So you have to deal with it. And here I would recommend you one of the tutorials from the Firebase team or one of many from the Internet.

Resources