Search code examples
firebaseflutterdartgoogle-cloud-firestorefirebase-security

Find document ID if the query know two of his fields, firestore rules


I'm trying my best to set up a functionality in my application that will allow people who know a group's login and password to join it.

Each group has a document in the "Groups" collection, and each user has a document in the "Users" collection.

To keep the id and the password information, I have another collection named "AuthGroups", containing as many documents as there are groups, with two fields: "login" and "password". Each auth document has the same ID as the corresponding document the Groups collection.

So, here is my strategy: When the user valid the login and password, a first query is sent to the database, to find a document with theses credentials in the "AuthGroups" collection. If a document is found, its ID is used to do another query in the "Groups" collection to retrieve the group's data.

Queries could look like this:

var ID = await firestore.collection('AuthGroups')
  .where('login', isEqualTo: login)
  .where('password', isEqualTo: password)
  .get()
  .then((value) {
    return value.docs.first.id;
  });

var groupName = await firestore.collection('Groups')
  .doc(id)
  .get()
  .then((value) {
    return value.get('name');
  });

Now, let's speak about firestore rules to make it secure... To prevent someone malicious from seeing all documents in my "AuthGroup" collection. I told myself that my rules need to only allow queries containing both "login" and "password" fields. But I don't know how to do it right, and if it's even possible... Same thing for the documents in the "Groups" collection: users can only get a document if they know its ID.

A solution could be to name my documents in my "AuthGroup" collection like "login + password", and store the group's ID in it. And in my rules, allow only list requests like that:

service cloud.firestore {
  match /databases/{database}/documents {
    match /AuthGroup/{organization} {
      allow list: if request.auth != null;
    }
  }
}

Solution

  • I told myself that my rules need to only allow queries containing both "login" and "password" fields. But I don't know how to do it right, and if it's even possible.

    It's not possible. You can't check for specific query parameters in security rules.

    A solution could be to name my documents in my "AuthGroup" collection like "login + password", and store the group's ID in it. And in my rules, allow only list requests like that

    Yes, that is a possible solution. Or you can hash a concatenation of login and password strings so you don't expose them in the document id or exceed the max length of that ID.