Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the reference data type in Firestore Rules

I want to define a rule that allows a user only to update his own items and an admin to update all.

As uid_of_logged_in_administrator I should be able to update both items/item__1 and items/item__2 - this works.

As uid_of_logged_in_user I should be allowed to update items/item__1 but not items/item__2 - this does not.

Obviously the problem is I do not know what the data type [Cloud Firestore references] represents in rules.

I've read through the documentation on rules and been trying different things.

if request.auth.uid == resource.data.owner                           | false
if request.auth.uid == resource.data.owner.id                        | false
if request.auth.uid == resource.data.owner.__id__                    | false
if resource.data.owner is string                                     | false
if resource.data.owner is path                                       | true
if resource.data.owner == path('users/uid_of_logged_in_user')        | false 
if request.auth.uid == resource.data.owner[6]                        | false

So it seems that the resource.data.owner is a path.

But how do I obtain the id for this reference?

One of my reasons for creating this reference is then the owner property can either be a box or an user. eg. {owner: '/users/uid_of_logged_in_user'}, {owner: '/boxes/box__1'}

I could of course just add a property with the users uid as a string to the item instead of as a reference. But then i would need to have two diffrent properties for box or user as owner.

My rules

service cloud.firestore {
  match /databases/{database}/documents {

    function isAdmin() {
      return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "admin";
    }
    function isAuth() {
      return request.auth.uid != null;
    }

    match /users/{uid} {
      allow read:   if isAuth();
      allow write:  if isAdmin();
    }

    match /items/{umbId} {
      allow read:   if isAuth();
      // THIS IS THE ISSUE. IT DOESENT WORK.
      allow update: if request.auth.uid == resource.data.owner 
      allow write:  if isAdmin();
    }
  }
}

The structure of my database is as follows

users 
  # documentid(uid_of_logged_in_user)
    - name: 'My name'                                           // string
    - address: 'My address'                                     // string
  # documentid(uid_of_logged_in_administrator)
    - name: 'Another one'                                       // string
    - address: 'His address'                                    // string
    - role: 'admin'

items
  # documentid(item__1)
    - owner: 'users/uid_of_logged_in_user'                      // reference
    - name: 'The first item'                                    // string
  # documentid(item__2)
    - owner: 'users/uid_of_logged_in_administrator'             // reference
    - name: 'The first item'                                    // string

boxes
  # documentid(box__1)
    - name: 'First Box'                                         // string
  documentid(box__2)
    - name: 'Second box'                                        // string
like image 439
Troels Lenda Avatar asked Jan 19 '18 11:01

Troels Lenda


People also ask

What is reference data type in firestore?

REFERENCE DATA TYPE IS ONE OF THE MANY DATA TYPES OF CLOUD FIRESTORE . THIS DATA TYPE ACTS LIKE FOREIGNKEY EVEN THOUGH IT IS NOT ACTUALLY A FOREIGNKEY . THE MAIN ADVANTAGE OF USING IT IS TO REFER A CERTAIN DOCUMENT TO ANOTHER DOCUMENT .

How do references work in firestore?

< T > A DocumentReference refers to a document location in a Firestore database and can be used to write, read, or listen to the location. The document at the referenced location may or may not exist. A DocumentReference can also be used to create a CollectionReference to a subcollection.

How do I set rules for firestore database?

To set up and deploy your first set of rules, open the Rules tab in the Cloud Firestore section of the Firebase console. Write your rules in the online editor, then click Publish.

How do references work in Firebase?

A Reference represents a specific location in your Database and can be used for reading or writing data to that Database location. You can reference the root or child location in your Database by calling firebase. database(). ref() or firebase.


1 Answers

if resource.data.owner == /databases/$(database)/documents/users/$(uid_of_logged_in_user) should work.

like image 95
mono Avatar answered Oct 14 '22 08:10

mono