5

I'm trying to secure my Firebase (google cloud storage) files based on user data. In firestore, I use a rule based on getting database content (look up the uid in users table and match a field) and that's working fine. I'm trying to use the same kind of rules in firebase storage but in the simulator I get Error: simulator.rules line [12], column [17]. Function not found error: Name: [get].; Error: Invalid argument provided to call. Function: [get], Argument: ["||invalid_argument||"]. My rules look like this:

  match /b/{bucket}/o {
    function isAuth() {
      return request.auth != null && request.auth.uid != null
    }
    function isAdmin() {
      return isAuth() &&
      "admin" in get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles;
    }
    function clientMatch(client) { // expects user's "client" field to be ID of client
      return isAuth() &&
      client == get(/databases/$(database)/documents/users/$(request.auth.uid)).data.client;
    }
    match /P/Clients/{client}/{allPaths=**} {
      allow read, write: if isAdmin() || clientMatch(client);
    }
  }
}

Line 12 is the one beginning client == get, in clientMatch(). I haven't been able to tell whether these functions are only supported for Firestore (db) rules, or whether they should work for storage as well.

If this doesn't work, what are my options? How do people look up user data for Firebase storage security?

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
GaryO
  • 5,873
  • 1
  • 36
  • 61

2 Answers2

10

You currently can't reference Firestore documents in Storage rules. If you would like to see that as a feature of Storage rules, please file a feature request.

Consider instead using a Cloud Functions storage trigger to perform some additional checks after the file is uploaded, and remove the file if you find that it's not valid.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
2

This is now possible with cross-service security rules. You have to use firestore. namespace before the get() and exists() functions as shown below:

function isAdmin() {
  return isAuth() && "admin" in firestore.get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles;
}

Do note that you'll be charged for read operations just like in Firestore security rules.

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84