Jonathan
Jonathan

Reputation: 4699

How to Get Data From Request Path in Firestore Rules

I am trying to figure out how to get an array from the path on an update or create in order to create validators based on the path data:

function test() {

  // option 1
  return string(request.path).split('/')[0] == 'databases';

  // option 2
  // return string(request.resource.__name__).split('/')[0] == 'databases';
}

match /posts/{document} {
  allow update: if test();
  ...
}

I have tried both of the previous examples with request.resource.__name__ and request.path... How do I parse the data out of the requested path?

Thanks,

J

Upvotes: 3

Views: 975

Answers (2)

Jonathan
Jonathan

Reputation: 4699

So, there is not way to ultimately change these path variables into an array or string that I can find:

  • request.resource.name
  • request.path
  • resource.name
  • any path() type

We need to change them into an array, to get their size. We need to get their size, to get the last few values. This would obviously be useful for universal functions that work on any number of sub-collections where you don't have to manually define the variable in the match.

Other posts like this one state that once upon a time ago, you could cast the data type to a string() like string(request.path), but this no longer works.

You could do something like this:

function doSomething() {
  return (request.path[4] && something1())
  || (request.path[6] && something2())
}

Of course, you don't want to do this for 5 levels of sub-collections. Ultimately, you just can't have a universal function without defining the variables before.

Perhaps Frank Van Puffelen can get the size() function or the toString() function added to the path variable.

J

Upvotes: 0

Peter Obiechina
Peter Obiechina

Reputation: 2835

Lets assume this is my request.path /databases/%28default%29/documents/posts/123456.

function test(docId) {
  // request.path supports map access.
  return request.path[4] == '123456'; // this will return true;
  return request.path[3] == 'posts'; // this will return true;
  return docId == '123456'; // this will return true;
}
match /posts/{documentId} {
  allow update: if test(documentId);
}

So if your path has 5 segments, request.path[4] && request.path[3] will return the last 2 segments.

Upvotes: 5

Related Questions