Untitled

 avatar
unknown
plain_text
5 months ago
1.9 kB
2
Indexable
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.database();

// Constants for rate limiting
const RATE_LIMIT = 5; // Maximum 5 writes allowed
const TIME_WINDOW = 60 * 1000; // 1 minute in milliseconds

// Cloud Function to handle write requests with rate limiting
exports.rateLimitedWrite = functions.https.onRequest(async (req, res) => {
  const userIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  const ipRef = db.ref('rateLimits/' + userIp.replace(/\./g, '_')); // Store IP as key (replace dots)

  try {
    const snapshot = await ipRef.once('value');
    const now = Date.now();
    const data = snapshot.val();

    // Initialize variables
    let lastRequestTime = 0;
    let requestCount = 0;

    if (data) {
      lastRequestTime = data.lastRequestTime;
      requestCount = data.requestCount;

      // Check if the time window has passed
      if (now - lastRequestTime > TIME_WINDOW) {
        // Reset the count if time window has passed
        requestCount = 1;
      } else {
        // Check if rate limit exceeded
        if (requestCount >= RATE_LIMIT) {
          return res.status(429).send('Rate limit exceeded. Try again later.');
        }

        // Increment the request count within the time window
        requestCount += 1;
      }
    } else {
      // First request for this IP
      requestCount = 1;
    }

    // Update the request time and count in Realtime Database
    await ipRef.set({ lastRequestTime: now, requestCount });

    // Now proceed to perform the actual database write
    await db.ref('someCollection').push({
      data: 'Some data',
      createdAt: now,
    });

    return res.status(200).send('Write successful');
  } catch (error) {
    console.error('Error handling rate limit:', error);
    return res.status(500).send('Internal server error');
  }
});
Editor is loading...
Leave a Comment