2

I'm trying to use the Google Authentication provider and then use the information for an authenticated user in a Database Rule to restrict access to data. For example, say I sign in with my Google id me@gmail.com.

Something kind of like the following (taken from the firestore docs):

    let provider = new firebase.auth.GoogleAuthProvider();
    let result = await firebase.auth().signInWithPopup(provider);

    let token = result.credential.accessToken;
    let user = result.user;
    // ...

In the above user.email would be me@gmail.com at this point.

Now how do I use that info in a rule to allow writing to the data. I thought it would be something like:

    match /events/{events} {
        allow write: if request.auth.uid = // Something?
    }

but I cannot figure out how to know what to compare to uid. Ideally it would be the email address (i.e. something human-readable).

My goal here is that I as the administrator keep a list of authorized users, and then they can come log into my app and access the data.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • `request.auth.token.email` is the email address of the user, according to the [documentation](https://firebase.google.com/docs/reference/rules/rules.firestore.Request#properties). But it's not always going to be present. It's better to use the UID, which will always be there. – Doug Stevenson Sep 09 '19 at 02:30
  • How does one find the UID to compare to? i.e. for a user like me@gmail.com how to I obtain that UID? Do I need an additional flow that a user registers first and requests access to get this UID? – Dan Sturman Sep 09 '19 at 02:32
  • All Firebase Authentication accounts are assigned a UID. You can see it in the console, and it's available in every SDK, both client and server. It's the core piece of data that Auth works with, and it's the best way to keep track of the user and their permissions. Email address is problematic, since they can change over time, and the are not case sensitive. It's advisable to design and organize everything about a user around the UID. – Doug Stevenson Sep 09 '19 at 03:25

1 Answers1

0

Like Doug Stevenson wrote in the comments you have to use request.auth.token.email. If you want to compare the email in your security rules, you also have to store the email address of the user in your firestore db so you can compare like this:

match /events/{events} {
        allow write: if request.auth.token.email == resource.data.email; 
    }

or you do it with the uid like this:

match /events/{events} {
        allow write: if request.auth.uid = resource.data.uid; 
    }

Of course you have to store the uid in your firestore db, too.

Constantin Beer
  • 5,447
  • 6
  • 25
  • 43
  • Thank you! Two related questions: 1) if I wanted to store the UID how would I get it? 2) In your example resource.data.email is just some other collection I create? i.e. what is resource in your example. – Dan Sturman Sep 09 '19 at 02:40
  • 1.) One post that might help is this: https://stackoverflow.com/questions/38352772/is-there-any-way-to-get-firebase-auth-user-uid – Constantin Beer Sep 09 '19 at 02:47
  • 2.) Here I recommend to watch this very helpful video: https://www.youtube.com/watch?v=eW5MdE3ZcAw&t=1s – Constantin Beer Sep 09 '19 at 02:48
  • And if you think my answer was helpful I would appreciate it if when you mark it as accepted by clicking the check mark. :) – Constantin Beer Sep 09 '19 at 02:49
  • 1
    You will be having UID at the time of user creation.This would be a unique one and you have to use that UID as document id.For your second question,Resource is predefined variable in firestore security rule and it points towards the documents you are trying to fetch. – Dev Sep 09 '19 at 02:52