I have a site similar to stack overflow where users can up and down vote posts. My question is how can I efficiently save this information to firestore under the Vuejs / Firestore/ VUEX architecture? How do other sites like stackoverflow/ reddit handle this?
I don't want to save directly on click because Firestore charges by the write and it would be very easy for a user to toggle up/ down votes many times consecutively. I also have a number of cloud functions this would trigger, each of which take time to complete.
I see a few alternatives. I could set a 2 second timer interval once a vote is cast, and if it doesn't change in that time, commit it to firestore. This has the downside of not working when the user leaves the page too quickly and after testing a few bigger sites, this approach seems to be of lower quality.
Another alternative is to save on page refresh/ exit with VUEX. Although the solutions I have found for this seem to rely on using the window object, which I hear may not work well if/ when I implement SSR into my app.
Perhaps there is a built in solution for this?
A common way to protect your back end against malicious users is to add a rate limit on certain events. In your case the up/down vote events.
Your first approach
You mention comes very close to the way rate limiting works. Just instead of firing the event to firestore 2 seconds after the user clicked and nothing has changed you could also fire the event immediately and then block any events for 2 seconds. This way the user can leave the page in the 2 seconds and the up/down vote will still be persisted in your database.
Your second approach
This is actually some I've never tried but just because you already mentioned the potential problems that come along in combination with SSR and the complexity of saving it to a temporary local state made me think that this approach might not be worth the work.
exaple solution
I copied this from a github issue comment, see the jsfiddle as an examp:
There are solutions you can do for per-user rate limiting using Rules
link to fiddle
http://jsfiddle.net/firebase/VBmA
We've discussed exposing this information, but at present we don't expose quota, rate limiting, or billing metrics. There are likely better ways of configuring these things than Rules (which are primarily for authN/Z, resource definition, type validation). The worry about exposing them is having a proliferation of different config files (firestore.quota, firestore.billing, firestore.rules, etc.) that confuse users unnecessarily.
issue: https://github.com/firebase/firebase-js-sdk/issues/647#issuecomment-380303400