TheWhiteSharp
TheWhiteSharp

Reputation: 59

Firestore Rules get is always null or errors out

it's about isAllowedWorkDayLocationData (checks if user-document.teamId and WorkDayLocationData.teamId is the same) - the global read seems to work fine and also the users{users} seems to work.

I Try to compare the property .teamId of the accessed document and the requesters /users/-Document .teamId.

Somehow it always returns false or errors out, im not sure what of both... i checked both documents and teamId is given.

rules_version = '2';
service cloud.firestore {

  
  function isAllowedWorkDayLocationData(docId, userUid) {
  return 
    get(/databases/{database}/documents/users/$(userUid)).data.teamId == 
    get(/databases/{database}/documents/workDayLocationDatas/$(docId)).data.teamId;
  }  
  
  match /databases/{database}/documents {
    match /{document=**} {
      allow read;
    }
    
    match /workDayLocationDatas/{docId} {
      allow write: if isAllowedWorkDayLocationData(docId, request.auth.uid);
    }
    match /users/{user} {
      allow write: if request.auth.uid != null;
    }
  }
}

This is my Query from the Angular Application (this was working until i implemented the rule)


this.afStore.collection<WorkDayLocationData>('workDayLocationDatas', ref => ref
        .where('teamId', '==', this.teamId)
        .where('locationId', '==', this.locationId)
        .where('date', '==', this.helpers.toFireStoreDate(this.workDay.date))
        .limit(1))
        .snapshotChanges()
        .pipe(first())
        .subscribe((actions: DocumentChangeAction<WorkDayLocationData>[]) => {
          console.log("i did something");
          const data = actions[0].payload.doc.data() as WorkDayLocationData;
          const id = actions[0].payload.doc.id;
          const newPersonUids = [...data.slotsPersonUids, user.uid];
          this.afStore.collection<WorkDayLocationData>('workDayLocationDatas')
            .doc(id)
            .update({
              slotsUsed: newPersonUids.length,
              slotsPersonUids: newPersonUids
            });
        });
    });

WorkDayLocationData interface for Properties:


export interface WorkDayLocationData {
    date: string;
    locationId: string;
    locationName: string;
    teamId: string;
    slotsUsed: number;
    maxSlots: number;
    slotsPersonUids: string[];
}

Upvotes: 0

Views: 312

Answers (1)

TheWhiteSharp
TheWhiteSharp

Reputation: 59

function isAllowedWorkDayLocationData(docId, userUid) {
  return 
    get(/databases/{database}/documents/users/$(userUid)).data.teamId == 
    get(/databases/{database}/documents/workDayLocationDatas/$(docId)).data.teamId;
  }  

So it turns out {database} should be $(database) and thus the correct code for the function would look like this:

  function isAllowedWorkDayLocationData(docId, userUid) {
  return 
    get(/databases/$(database)/documents/users/$(userUid)).data.teamId == 
    get(/databases/$(database)/documents/workDayLocationDatas/$(docId)).data.teamId;
  }  

Upvotes: 1

Related Questions