0

Is there a way to stop writes to a document if the amount of documents in another collection has reached a certain number? Keep in mind concurrency- multiple users writing at the same time!

  • 1
    It'd be closely related to this: https://stackoverflow.com/questions/56487578/how-do-i-implement-a-write-rate-limit-in-cloud-firestore-security-rules If you're having problems while implementing that approach, post back here with what you tried. – Frank van Puffelen Jan 26 '20 at 18:16
  • @FrankvanPuffelen I think you misunderstood the question but that link is definitely something I should think of. –  Jan 26 '20 at 19:14
  • If you think I misunderstood the question, can you clarify it? – Frank van Puffelen Jan 26 '20 at 19:23
  • @FrankvanPuffelen I need to check if the total amount of docs in a collection has reached 0, and if yes then dont post to DB. However, this needs to be done keeping in mind concurrency issues. –  Jan 26 '20 at 19:26

2 Answers2

0

Sure:

  1. Have the write to Firestore happen within a Cloud Function (callable or https)

  2. In the function, have an if clause that checks the number of documents prior to writing

  3. You'd have to also do the validation logic of whether the user has permission to write within that function, rather than through a Firestore rule.

Regarding actually counting the number of documents, the best method would depend on how many there are, and how quickly they're being written to. This SO thread addresses those issues: Cloud Firestore collection count

ultraGentle
  • 5,084
  • 1
  • 19
  • 45
0

You can prevent writes to that document using Firebase's server-side security rules, which are automatically enforced for writes from any client SDK.

If for example you have a document with a number that must be say greater than 0 to be allowed to write a new document, you can enforce that with:

service cloud.firestore {
  match /databases/{database}/documents {
    match /orders/{order} {
      // Only allow an order for a product of there's any stock left
      allow create: 
        if get(/databases/$(database)/documents/products/$(request.resource.data.productid)).data.stock > 0
    }
  }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    The problem is that the OP wants to check the number of documents in a collection, which is not available in security rules. – Doug Stevenson Jan 26 '20 at 20:14
  • @DougStevenson changed my approach, I have a field called Amount now in each document of the collection. So, now I think I can use transactions. –  Jan 26 '20 at 20:34
  • Frank, why not use transactions? –  Jan 26 '20 at 20:35
  • 1
    Transactions are a client-side mechanism. Which means that any malicious user can bypass them by writing their own code against your configuration data. So while you should use transactions, they can't replace server-side security rules. – Frank van Puffelen Jan 26 '20 at 21:01
  • @FrankvanPuffelen how can they actually bypass the configuration data? –  Jan 27 '20 at 09:58
  • @DougStevenson can I get your opinion on this? Can someone bypass my configuration data if I implement transactions in client-side? –  Jan 27 '20 at 10:00