Ad

Firestore Rules Break If The Document Path Has A Comma

So, I am building a multi tenant application which involves multitude of collections and user invitation. Since I don't know which user ID the signup is going to use and I want the companies to start making changes and updates to their user data I am pre setting the user ID and I use it in several paths as:

/companies/{company}/customers/{userId}
/users/{userId}

Now, this userId is pretty much the email with the dot replaced by a comma. The dot is a character not allowed in firebase but the comma is, and viceversa with emails so it makes sense and there is no problem there.

The issue is when I need to make some rules. For example I have this in the configuration since I want admins to access every company:

  function cleanEmail(){
        return request.auth.token.email.split('.').join(',') //Here I also tried %2C
    }

    function isSuperadmin() {
      return exists(/databases/$(database)/documents/admins/$(cleanEmail()))
    }


 match /companies/{company} {
      allow write: if isSuperadmin();
      allow read: if isSuperadmin() || belongsToCompany(company)
}

The simulator was breaking but I could not understand why, so I even sent a bug report. Eventually I tried making the path hard coded and then I found the problem:

function isSuperadmin() {
      return exists(/databases/$(database)/documents/admins/test,[email protected],com) //Same issue with get()
    }

enter image description here

I tried with exists() because I thought it could be a bug with get() but the issue remains. I believe this should be a bug since that is a valid Firestore path and I have seen some people already using this "clean email" strategy.

Funny thing is that this was not happening during first testing and I realized that this bug only happens if the comma is BEFORE the @. If you remove the one before that, and leave the second one, seems to work:

enter image description here

I might add a new step to the clean email that turns that into base64 and that might work tho. If someone has a solution great.

Ad

Answer

I do something similar that looks like this in outline:

/invitation
    /fb-generated-doc-name
        email: [email protected]
        trip: db-ref-to-trip

/usertrips
    /doc-name-is-UID
        trip: db-ref-to-trip

/trips
   /fb-generated-doc-name
       { ... describes the trip ... }

The outline for onCreate auth'd user is:

exports.authDidCreateUser = functions.auth.user().onCreate((authUser, context) => {
  /* 
      find invitation where email == authUser.email
      let docref = collection('usertrips').doc(authUser.uid)
      docref.set({ trip: invitation.trip })
  */
});
Ad
source: stackoverflow.com
Ad