title: How to prevent attacks on firebase functions?
body: <p>I am seeing some very unusual traffic in my cloud functions and I can only attribute them to an attack (note that I am using the free Spark plan).</p>
  
  <p>The cloud function that gets spammed is:</p>
  
  <pre><code>exports.onPlayerSolvedPuzzle = functions.database.ref('/U/{userId}/CP/{puzzleId}/S')
  .onCreate((snapshot, context) =&gt; 
  {
  ...
  </code></pre>
  
  <p>As you can see it is designed to be called when a new data is added in my DB at the path /U/{userId}/CP/{puzzleId}/S</p>
  
  <p>My DB rules specify that only an authenticated user can write data with his ID, additionally I check that this data entry doesn't exist already</p>
  
  <pre><code>{
    "rules": 
    {
      "U":
      {
        "$user_id":
        {
          ".read" : false,
          ".write": "auth.uid != null &amp;&amp; $user_id === auth.uid",
          "CP":
          {
            "$puzzle_id":
            {
              "S":
              {
                ".validate": "!data.exists()"
              },
  ...
  </code></pre>
  
  <p>Finally, I have only enabled the "Play Games" and "Game Center" authentications so no anonymous account or email/password account can be used to modify my DB.</p>
  
  <p>When the attacks happen the number of maximum simultaneous connections to my DB jumps from the average of 20 to 100, and the number of cloud function calls jumps from 1000 or less per day to 20000 or more per day eating up my monthly usage quota quite a bit.</p>
  
  <p>What should I do to protect the cloud function calls that I have not already done?</p>
  
  <p>P.S.: when 'onPlayerSolvedPuzzle' executes it writes to another part of the DB to increment the number of people who have solved the puzzle with this 'puzzle_id' (or create an entry if there was none). I have code in place to see if there are entries in that part of the DB that are related to 'puzzle_id' that should not exist (I know the puzzle_id of all the puzzles). When I run this code I don't see any problem at all, so I believe the function is not called with random puzzle_id in the path.</p>