Home > Blockchain >  Firebase Realtime Database Rules checking for array contains
Firebase Realtime Database Rules checking for array contains

Time:04-14

My auth token includes a stores property. This property is an Array that includes ID's of all stores the user is allowed to access. For example: stores: ['abc123', 'def456'].

Now, in my Firebase Realtime Database, I am saving store specific data like this:

{
  "stores": {
    "abc123": {
      "data": "mydata"
    },
    "def456": {
      "data": "mydata"
    }
  }
}

Users are allowed to access the realtime database data if their stores property array includes the storeID specific data they want to access.

What I would like my rules to look like:

{
  "rules": {
    "stores": {
      "$store_id": {
        ".read": "auth.token.stores.includes($store_id)"
      }
    }
  }
}

This is not possible. I get the following error:

Error saving rules - line 5: type error: function call on target that is not a function.

Is it possible to search trough token property arrays in the firebase rules or will I have to use an object? Thanks for any answers!

CodePudding user response:

Firebase Realtime Database does not have any includes() to check if a value if present in an array or not. You can store the claims as a map instead of an array as shown below:

// custom claims
{
  stores: {
    store1: true,
    store2: true,
    store3: false
  }
}

Then you can use the following rules to check if user has access to a particular store or no:

{
  "rules": {
    "stores": {
      "$store_id": {
        ".read": "auth.token.stores[$store_id] == true"
      }
    }
  }
}

CodePudding user response:

You can use in operator from List

v in x
Check if value v exists in list x.

'a' in ['a','b'] == true

Sample Security Rules how it can be done

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      
      match /stores/{storeId} {
        allow read: if isAuthenticated() && isUserAllowed();
      }
      
      function isAuthenticated() {
        return request.auth != null;
      }

      function isUserAllowed() {
        return request.auth.uid in resource.data.stores
      }

    }
  }
}
  • Related