Flutter/Firebase: Admin features in-app or cloud functions?

2,624

The goal is to have users with admin privileges

Since you are using the Authentication service you already have half of the solution: with authentication you can identify each user who is using your app.

The other part is Authorization: this is normally done with Security Rules in Firebase, both for Firestore and Cloud Storage.

To be able to authorize certain users (identified through authentication) with Admin privileges, you need to know which users have the admin role in such a way you authorized them to execute the admin functions.

One possible way to identify the admin users is to have an isAdmin flag in some user documents in Firestore, as you mention in your question. There is an example of Firestore Security Rule using this approach in the documentation.

HOWEVER, you will encounter some problem if you want to use this flag (stored in Firestore) with Security Rules for Cloud Storage. At the time of writing, it is not possible to read the value of a Firestore document in Security Rules for Cloud Storage.

The solution is to use Custom Claims. You will find all the details in the doc on how to implement it in such a way it fulfill your needs.

Can I build an Admin Panel inside the client app?

Yes, you can very well do that. As soon as your security is correctly implemented (through Authentication and Security Rules, as explained above), there is nothing that prevents you to develop an Admin panel. If a user that is not admin can access the Admin panel, he/she will not be able to perform the admin actions (i.e. writing/editing/removing Firestore or Cloud Storage data).

Moreover, with Custom Claims, you can access them in the front-end to modify the client UI based on the user's role or access level (i.e. showing the pages, buttons and menu items of the Admin module only to admin users -note however that this does not prevent someone to reverse engineer your app and execute the queries dedicated to admin users: this is why it is key to correctly implement the Authentication and Security Rules parts-). See this section in the Custom Claims doc.

Should I build an Admin Panel in another app and using Cloud Functions?

If you don't want to over-complexify your app with some logic to hide/show the Admin panel elements (based on Custom Claims, see above) you can very well build the Admin Panel in another app.

If you have specific needs/access restrictions that cannot be implemented through standard Security Rules you could very well use some Cloud Functions to check the user is an admin and to execute the writing/editing/removing admin actions (note however that while it is quite easy to interact with Firestore from a Cloud Function, it can be a bit more tricky with Storage: using the Cloud Storage Client SDKs is much easier than interacting with Cloud Storage through Cloud Functions).

You would preferably use Callable Cloud Functions, since "with callables, Firebase Authentication and FCM tokens, when available, are automatically included in requests". (See https://firebase.google.com/docs/functions/callable).


Side Note: You may be interested by this article, which details how to to create an Admin module for managing users access and roles. (Disclaimer: I'm the author).

Share:
2,624
Rasmus Lian
Author by

Rasmus Lian

Updated on December 17, 2022

Comments

  • Rasmus Lian
    Rasmus Lian over 1 year

    I'm writing an app with Flutter and Firebase (using both Firestore, Storage and Authentication so far).

    Currently the app shows content from Firebase, but now I'm trying to figure out how the best way is to implement writing/editing/removing stuff in Firebase.

    The goal is to have users with admin privileges.

    My question is if I can build an Admin Panel inside the client app (which would be ideal), or if that's considered bad practice and I should build an Admin Panel in another app and using Cloud Functions.

    For example, currently I perform Authentication (signup/register) in the Flutter/Dart code and when registering it creates a field in Firestore isAdmin = false, which I then can manually set to true (if I want) in the Firestore console. Could this somehow be an "unsafe" way of doing this?

    • Doug Stevenson
      Doug Stevenson over 4 years
      FYI backtick quotes are for marking bits of code, not highlighting names of products.
    • Doug Stevenson
      Doug Stevenson over 4 years
      I don't know what you mean by unsafe. Does the change you're making satisfy the needs of your app? If so, then do it.
    • Rasmus Lian
      Rasmus Lian over 4 years
      @DougStevenson What I meant by "unsafe" was since I initialize a User on the client side, could the isAdmin field somehow be reverse-engineered by someone else and somehow be set to true? Thanks in advance
    • Doug Stevenson
      Doug Stevenson over 4 years
      You will want to look into security rules if you want to limit what an end user can do to data in documents. Without good security rules, your data could be completely unsafe.
    • Rasmus Lian
      Rasmus Lian over 4 years
      Thank you for this clarification. I will take a closer look on creating strong security rules :)
  • Rasmus Lian
    Rasmus Lian over 4 years
    A big thank you for this very well explained and clear explanation. I will definately read your article on this. So the bottom line is that I don't have to use Cloud Functions and can use Custom Claims instead? And since I initialize a User on the client side, could the isAdmin field somehow be reverse-engineered by someone else and somehow be set to true? Thanks in advance.
  • Renaud Tarnec
    Renaud Tarnec over 4 years
    If you want to use an isAdmin flag you need to write some Security Rules to only allow specific users (Super Admin?) updating it. If someone identifies the collection name where the users docs are stored and the id of one document he could modify the data if security rules are not in place. If you use Custom Claims you don't have this problem, since they can only be set from a privileged server environment by the Firebase Admin SDK (i.e. from a server that you fully control or a Cloud Function in your Firebase Project that runs back-end code). This is where my article can help you :-)
  • Renaud Tarnec
    Renaud Tarnec over 4 years
    "So the bottom line is that I don't have to use Cloud Functions and can use Custom Claims instead?" -> Not exactly. The way you refer to Cloud Functions in your question is more for using them as a "middleware" between the user front-end and the back end (Firestore and/or Storage) instead of relying on the Client SDKs and Security Rules. See this article: medium.com/firebase-developers/…
  • Rasmus Lian
    Rasmus Lian over 4 years
    Ah, I see. Yet again a huge thank you for a thorough explanation. I will definately dive into the two articles you linked, and together with your answers I think I now understand a lot better the whole conecpt behind it all. Thanks :)