1
votes

I am writing firebase security rules, and I am attempting to get a document that may have a space in its documentID.

I have the following snippet which works well when the document does not have a space

    function isAdminOfCompany(companyName) {
        let company = get(/databases/$(database)/documents/Companies/$(companyName));
        return company.data.authorizedUsers[request.auth.uid].access == "ADMIN;
    }

Under the collection, "Companies", I have a document called "Test" and another called "Test Company" - Trying to get the document corresponding to "Test" works just fine, but "Test Company" does not seem to work, as the company variable (first line into the function) is equal to null as per the firebase security rules "playground".

My thought is that there is something to do with URL encoding, but replacing the space in a documentID to "%20" or a "+" does not change the result. Perhaps spaces are illegal characters for documentIDs (https://cloud.google.com/firestore/docs/best-practices lists a few best practices)

Any help would be appreciated!

EDIT: As per a few comments, I Will add some additional images/explanations below.

Here is the structure of my database enter image description here

And here is what fields are present in the user documents enter image description here

In short, the following snippet reproduces the problem (I am not actually using this, but it demonstrates the issue the same way)

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
      
    match /Users/{user} {
      allow update: if findPermission(resource.data.company) == "MASTER" 
    }
        
    function findPermission(companyName) {
      let c = get(path("/databases/" + database + "/documents/Companies/" + companyName));
      return c.data.authorizedUsers[request.auth.uid].access;
    }        
  
  }
}

When I try to update a user called test@email.com (which belongs to company "Test"), the operation is permitted, and everything works exactly as expected.

The issue arises when a user, called test2@email.com, who belongs to company "Test Company" comes along and makes the same request (with authorization email/uid updated in playground, to match what is actually found in the company structure), the request fails. The request fails, since the get() call (line 1 of the function) cannot find the Company document corresponding to "Test Company" - indicated by the variable "c" being null in the screenshot (see below) - IT IS NOT NULL WHEN LOOKING FOR "Test"

Below is a screenshot of the error message, as well as some of the relevant variables when the error occurs

enter image description here

1
I would setup your system so a document cannot be created with a space, and write a function to replace it with %20 in any occasion where a space would be used. That will prevent issues in the future and help with storage.Mallard
Thanks for the quick reply! I have tried replacing spaces with %20 as such """ companyName.replace(" ", "%20") """ and still no luck. I even checked the path that this request was making is the same as a simple get directly to that document. The paths exactly match, but the get call still fails here. Both the direct get request, and the get request through this function, both call path "/databases/%28default%29/documents/Companies/Test+Company", but it only works If I make the get call directlyCedric Hansen
firebaser here I'm not sure I understand correctly: are you saying that get(/databases/$(database)/documents/Companies/$(companyName) fails to read the document of $(companyName) contains a space? That sounds like it'd be a bug to me, so can you: 1) confirm my understanding, 2) show more of a reproduction with code, the errors, and screenshots of the document (making it easier for us to reproduce the problem).Frank van Puffelen
Hi Frank, thats exactly right. If the variable companyName contains a space, the request fails. The exact same code (which authentication etc modified appropriately) works when there is no space in document id. I've edited my original question, and included extra details, pictures, and explanations. Please let me know if any additional clarification is necessary!Cedric Hansen

1 Answers

0
votes

Check to see what type of space just in case it is another non-printable character. You could convert it to Unicode, and check what it might be. However, it is considered bad practice to use spaces in naming variables and data structures. There are so many different types to consider.

    | Unicode | HTML   | Description        | Example | 
    |---------|--------|--------------------|---------| 
    | U+0020  | &#32   | Space              | [ ]     | 
    | U+00A0  | &#160  | No-Break Space     | [ ]     | 
    | U+2000  | &#8192 | En Quad            | [ ]     | 
    | U+2001  | &#8193 | Em Quad            | [ ]    | 
    | U+2002  | &#8194 | En Space           | [ ]     | 
    | U+2003  | &#8195 | Em Space           | [ ]    | 
    | U+2004  | &#8196 | Three-Per-Em Space | [ ]     | 
    | U+2005  | &#8197 | Four-Per-Em Space  | [ ]      | 
    | U+2006  | &#8198 | Six-Per-Em Space   | [ ]      | 
    | U+2007  | &#8199 | Figure Space       | [ ]     | 
    | U+2008  | &#8200 | Punctuation Space  | [ ]     |
    | U+2009  | &#8201 | Thin Space         | [ ]      |
    | U+200A  | &#8202 | Hair Space         | [ ]      |