Search code examples
androidfirebasegoogle-cloud-firestorefirebase-security

Android | Firestore Rules | Check if username & phone already exists


I want to check if the user's username and phone number is unique. I have implemented it using FirebaseFirestore.getInstance().collection("Users").whereEqualTo("phone",ph).get().addOnCompleteListener(...);

This is my firestore rule:

service cloud.firestore {
  match /databases/{database}/documents {
        match /{document=**} {
        allow read: true;
        allow write: if request.auth.uid != null;
        }
      match /Users/{userID} {
            allow update: if request.auth.uid == userID 
                && (request.resource.data.username == resource.data.username
               || isUserNameAvailable(request.resource.data.username)
            );
        }
  }

The code works fine with no issues. I am checking this before the signInWithCredential method and hence the request.auth.uid will always be null. To make the code work ill have to keep allow read: true; But, now i am getting this warning

We've detected the following issue(s) with your security rules: any user can read your entire database

Is there any workaround to prevent this?


Solution

  • This is a common mistake developers make when using usernames. You gave anyone permission to read your whole database. And even if you manage to put that to only read Users anyone could read all your users data.

    I would recommend to remove the first allow read:true and write rules for each path as they should be. Also create a separated collection just for usernames and save all of them there like /usernames/${username} and /phones/${phone}. If the need to be saved together you can do that to.

    That way you can very easy check without any query if a username or phone exists by just checking if that path exsists in your database.

    You can very easy sync the users collection with those two and even write security rules that prevent creating users in the collection that have a username that already exists in the usernames collection.