Reputation: 2509
I was trying to write a rule that if the id of the document doesn't exist, then create a new document. My object is:
Message message = new Message(userId, title, messageBody, timestamp);
and I'm using WriteBatch
to create a new document and updating the same:
mWriteBatch.set(mMessageRef.document(messageId), message);
mWriteBatch.update(mMessageRef.document(mIntentMessageId), // params...);
After browsing through the docs and this site I've found out that if I use create
method, it only allows to write the data if it doesn't exist.
So I created a security rule like:
match /messages/{message} {
allow read;
allow create: if isSignedIn();
allow update, delete: if isSignedIn();
}
isSignedIn()
is just a method contianing request.auth != null
. This rule fails and overwrites the data. Now I tried:
match /messages/{message} {
allow read;
allow create: if request.resource.id != message;
allow update, delete: if isSignedIn();
}
This time also it overwrites the data instead of showing an error.
What am I doing wrong here? Any help is appreciated.
Update: As told by José David Aroesti in the comments, I have to change it to exists
and remove update
and delete
to work properly and from the app it's reflecting what it's suppose to do. But then how would I update
and delete
a document?
For example, when I'm using the below rules in Simulator, both are being executed as expected but when I'm testing it from the device, I'm always able to create a document even if it exists:
allow create: if !exists(/databases/$(database)/documents/messages/$(message));
allow update: if get(/databases/$(database)/documents/messages/$(message)).data.timestamp
< request.resource.data.timestamp;
Is it possible?
Upvotes: 2
Views: 2859
Reputation: 626
You can use the exists()
and get()
built-in functions to verify if the document exists or to access the document so you can read its data.
In this case, an example would be:
match /messages/{message} {
allow read;
allow create: if !exists(/databases/$(database)/documents/messages/$(request.resource.id));
}
And as @creativecreatorormaybenot suggested, you should not specify allow
expressions for update
and delete
so the data cannot be overwritten.
Here is a link to the documentation:
https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents
https://firebase.google.com/docs/reference/rules/rules.firestore
Upvotes: 7