0
votes

Here's the use case:

Any user can put in their email address (e.g., no auth), and then Firestore checks if there is a user doc with that email:

db.collection("users").where("email", "==", "USER_EMAIL")
  .get()
  .then(function(querySnapshot) {

    querySnapshot.forEach(function(doc) {
      // doc.data() is never undefined for query doc snapshots
      console.log(doc.id, " => ", doc.data())
    })

  })
  .catch(function(error) {
    console.error("Error getting documents: ", error)
  });

I want to limit being able to read a user's document unless the requested user email matches. Users don't log in before checking their email, so no request.auth information is coming in. How can I secure this? Is it possible without logging in?

Obviously this did not work because it isn't a write function:

function isUserEmail() {

  // doesn't work because it is a public-facing module (no auth):
  return request.auth.email == resource.data.email

  // doesn't work because not a write function:
  return request.resource.data.email == resource.data.email

}

match /users/{userID} {
  allow read: if isUserEmail()
}

Is there a way to pass parameters other that request.resource.data or request.auth?

2

2 Answers

2
votes

If you're trying to make use of the user's email address as known by Firebase Authentication, you can compare against request.auth.email for that.

allow read: if resource.data.email == request.auth.email;

But you should know that an email address is not guaranteed to be present for any given authentication provider. Using email address is not really the best way to limit access to a document. It's generally better to use the user's UID as assigned by Firebase Auth.

0
votes

As pointed out by Doug Stevenson, there's no way to make this use case secure. Will have to restructure a bit to use auth!