0

Objective : Limiting signedIn users to be able to write only 'N' times per day in firebase realtime database.

Schema : Tree of the database:

enter image description here

Condition Value : Object dipt contains now key and document-name is the date & time when a user wrote in database via the application.

dipt:
{
ip: "",
now: "Tuesday, September 29th, 2020, 11:48:00 PM",
reg: ""
} 

Problem Statement : Figure out a logic that isn't very resource intensive. I mean, I can get all search-data > Objs of a signedIn user and use foreach to make comparisons from now() and count to the value of 'N' but you & I, we both know that isn't going to be just very resource intensive but also a real pain in rear.

So, there is gotta be a simpler way of doing this. Any help, or any idea of doing this differently, or may be any past experience of dealing with such a scenario is highly appreciated. I look forward to hear from stack overflow geniuses and Firebase-Angular gurus.

Shaheer Wasti
  • 65
  • 1
  • 10
  • I'd recommend looking into the direction I took here for Firestre: https://stackoverflow.com/questions/56487578/how-do-i-implement-a-write-rate-limit-in-cloud-firestore-security-rules. So: ) keep a counter, 2) ensure the counter is updated on each write, 3) ensure the counter isn't updated more frequently than you want to allow. – Frank van Puffelen Sep 29 '20 at 23:02
  • @FrankvanPuffelen (puf). Thank you so much for giving a much needed direction. :) I developed a counter that is serving my purpose brilliantly. I learned many other concepts while implement this, and Doug I'd also like to thank you for I find the answers of many related questions in other threads posted by you. A big kudos! firebase team. :) – Shaheer Wasti Oct 01 '20 at 11:06
  • Thanks for reporting back Wasti. If you got a working solution, can you add it as a self-answer (similar to what I did in the link)? That way others can benefit from your learning. – Frank van Puffelen Oct 01 '20 at 13:52
  • Sure puf! I am definitely going to share a detailed self-answer after I some cleaning and refactoring my code. – Shaheer Wasti Oct 01 '20 at 14:16

1 Answers1

0

After gaining the insight of developing a counter from Puf, I wrote a cloud function to limit writing signedIn users into firebase realtime database for N time per day.

Export this function with your function name and initialize following:

//Date Variable for counter takes the date from server
const date = new Date(Date.now() - (Date.now() % 86400000))
//Base Reference for setting counter 
var baseRef = admin.database().ref(`/users/${userid}/${date}/${Date.now()}/`);
//Root Reference for per date
var rootRef = admin.database().ref(`/users/${userid}/${date}`);
//counter Reference
var counterRef = rootRef.child(`/counter`);

This tree will look something like this:

enter image description here

After setting up appropriate read/write rules for your realtime database, everytime a signedIn user who writes on a same date (remember we are taking date from server and not from user) will going to write under today's date and with a now() timestamp and updates the counter value.

//Getting value of counter in snapshot if > 0 execute the query & updates counter value

counterRef.once('value').then((snapshot) => { 
if(snapshot.val()>0){baseRef.set({"json":data});
        rootRef.child(`/`).update({
           "counter": snapshot.val()-1
          });
}
//On first Instance of a new date if the value of counter in snapshot 
is null because there is no counter created at this point

    else if (snapshot.val()==null){
baseRef.set({"json":data});
        rootRef.child(`/`).update({
           "counter": //counter max val
          });
}
else{ return res.status(200).json({
    res: "Limit Reached"
      })}

It's important to note here that I am using .update() even for the first time where there is no counter created. Please read the difference between .set() & .update() here.

I am no pro, but that is how I have written my counter. Feel free to let me know if there is more efficient way to achieve similar results.

Shaheer Wasti
  • 65
  • 1
  • 10