avatarAlex Mamo

Summary

This article provides solutions for handling the "PERMISSION_DENIED: Missing or insufficient permissions" error when interacting with Cloud Firestore, a NoSQL document database offered by Google Firebase.

Abstract

The article discusses the common error "PERMISSION_DENIED: Missing or insufficient permissions" that occurs when trying to perform a query against a Cloud Firestore database. It explains the cause of the error, which is a rejection of the operation by Firebase servers due to insufficient permissions. The author suggests avoiding this error by changing the rules in Cloud Firestore Security Rules. The article provides examples of insecure rules and recommends using more secure solutions, such as allowing access only to authenticated users and implementing granular rules based on user UIDs. The author also mentions a similar error, FAILED_PRECONDITION, which occurs when a Cloud Firestore index is missing. The article concludes by emphasizing the importance of securing databases wisely to improve user experience and prevent unwanted access.

Bullet points

  • The "PERMISSION_DENIED: Missing or insufficient permissions" error occurs when interacting with Cloud Firestore, a NoSQL document database offered by Google Firebase.
  • The error is caused by a rejection of the operation by Firebase servers due to insufficient permissions.
  • To avoid this error, the author suggests changing the rules in Cloud Firestore Security Rules.
  • The article provides examples of insecure rules, such as allowing anyone to read and write to the database, and recommends using more secure solutions.
  • The author suggests allowing access only to authenticated users and implementing granular rules based on user UIDs.
  • The article mentions a similar error, FAILED_PRECONDITION, which occurs when a Cloud Firestore index is missing.
  • The article concludes by emphasizing the importance of securing databases wisely to improve user experience and prevent unwanted access.

How to fix Firestore Error: PERMISSION_DENIED: Missing or insufficient permissions

A simple solution for handling Firestore error.

That’s by far the most common and annoying error that you can get when you try to perform a Query against a Cloud Firestore database for reading data, or when you try to create/update/delete Firestore documents. So I’m trying to show you in this article, a few solutions that can help you get rid of this error.

First of all, let’s understand what this error actually represents. Generally, when we interact with Firebase products, and something goes wrong, a FirebaseException will be thrown. When it comes in particular to Cloud Firestore, when something fails, there is a specific exception that is thrown which is called FirebaseFirestoreException. So according to the official documentation, this is:

  • A class of exceptions thrown by Cloud Firestore.

Since when interacting with Firestore there can be potentially multiple reasons why an operation can fail, there should be a way we can differentiate them. That’s the reason why the Firebase team has created a different “status code” for each type of Exception. All these codes are present in an enum that is nested under the FirebaseFirestoreException class that is called Code. There are 17 enum values, for each type of error we can get. The one that we are talking about is called:

  • public static final FirebaseFirestoreException.Code PERMISSION_DENIED

That occurs when:

  • The caller does not have permission to execute the specified operation.

What does it actually mean? We know that when we create a Query in Firestore, we can get as a result, the exact data we are interested in, or an Exception, but never both. That’s the same for all CRUD operations. So the failure listener will only be called once the data is rejected by the Firebase servers. So if it’s rejected, the above Exception is thrown containing the following error message:

  • PERMISSION_DENIED: Missing or insufficient permissions

This message is the same for all platforms, Android, iOS, and web.

How to avoid this error? Since this Exception is thrown because Firebase servers rejected the operation, the way we can fix this is by changing the rules in Cloud Firestore Security Rules.

As I saw in the last years, the initial response for most developers is to try to “fix” this error by using the following rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

Which I personally recommend against this! Setting true to both read and write operations, means that you allow anybody who knows your project ID to read from, and write to your database. Which is obviously bad, since malicious users can take advantage of it. It’s true that you can use these settings for a small amount of time for testing purposes, but never in a production environment. So there is another option in which you can limit access to your database to a fixed amount of time. By the time I’m writing this article, it’s 17'th June 2021. So you can use the following rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.time < timestamp.date(2021, 6, 18);
    }
  }
}

To limit the access for exactly one day (18'th June 2021). However, you might take into consideration the following, more secure solutions.

The most important part when it comes to security rules is the Firebase Authentication, meaning that you can allow access only to the users that are authenticated to perform operations in your database. The rules should look like this:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

If you need a more granular set of rules, for instance, to allow only the authenticated users, who have the value of the UID equal to the value of UID that comes from to authentication process, to be able to write to their own document, then you should consider using the following rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{uid} {
      allow create: if request.auth != null;
      allow read, update, delete: if request.auth != null && request.auth.uid == uid;
    }
  }
}

Remember, any other request will fail!

These are the most common ways you can use to avoid this error. Another similar error that is worth mentioning here is the one with the “status-code” FAILED_PRECONDITION, which occurs when:

  • The operation was rejected because the system is not in the state required for the operation’s execution.

For example, when a Cloud Firestore index is missing. I have answered a question on Stackoverflow regarding this topic:

In the end, is worth also mentioning that you’ll never get such an error if you are using Firebase Admin SDK. Why? Because all access to Cloud Firestore or the Realtime Database that comes from a backend server will bypass the security rules entirely. Security rules only apply to web and mobile client access.

Conclusion

Always secure your database wisely, once to never get such an error and improve UX, but also to throw unwanted visitors away.

If you wanna support me, please join me!

You can also see it on youtube:

#BetterTogether 🔥

Firebase
Firebaseauthentication
Firebasesecurityrules
Cloud Firestore
Recommended from ReadMedium