Ad

How To Properly Implement Firestore Database Rules To Prevent Update To Data When Certain Field Changed?

I am building a NodeJS Express app and am using Firebase as the backend. I am trying to secure my firebase backend, more specifically the firestore database with Firestore Security Rules. However, I cannot seem to get my security rules to trigger.

I have a route called /api/goalPRs/:goalPRId which updates a database ref with the body of the request by calling

const goalPRsRef = db.collection('goalProgressReports');
goalPRsRef.doc(goalPRId).update(newGoalPR).then(()=>({update: 'Success'}));

Now, each goalPR has a field called targetGoalId, which I want to be constant, I dont want that data to be editable. Hence I have tried to set up the following firestore security rule.

service cloud.firestore {
  match /databases/{database}/documents {
    match /goalProgressReports/{goalPR} {
      allow update: if request.resource.data.targetGoalId == resource.data.targetGoalId;
    }
  }
}

With this security rule I expect that any update to a document within goalProgressReport collection should be denied if the old targetGoalId is not equal to the new one. However, this is not the case. I can provide a new targetGoalId and it incorrectly updates.
Also, even when I try something like this with the security rules:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
       allow read, write: if false
    }
  }
}

I am still allowed to write to the database, even though from my understanding this rule shouldn't allow any reads or writes to the database. Is my understanding of how security rules work incorrect? How can I fix my goalProgressReport security rule to not allow updates if the targetGoalId has changed?

Ad

Answer

Since you're running on nodejs, that means you're using either the Cloud Firestore node SDK or the Firebase Admin SDK which wraps the Cloud SDK. In this case, security rules don't apply. They only apply to access coming directly from web and mobile applications, and not from the server SDKs. The server SDKs always bypass all security rules, because it's coming from a privileged service account.

Ad
source: stackoverflow.com
Ad