Search code examples
reactjsfirebasegoogle-cloud-firestorefirebase-authenticationfirebase-admin

Reactjs and Firebase: one login interface for user and admin or separate login interface?


I'm doing a school project using reactjs and Firestore that has 2 users; user and admin. These are the features:

User: User registers on the website. Upon registration, the system will generate a QR code for the user to be scanned. Upon scanning, the vaccination status of the user will be updated such as the vaccine type, dose, date of vaccination, and etc. The user may also input side effects they've experienced, and view the vaccination graph reports.

Admin: Admin can log in and scan the qr code, view vaccination graph reports, Vaccine (CRUD), list of the users

  • Is it okay to have one login interface for both users and admin? Are there any security risk or defining the security rules is already enough?
  • Or is it preferable to have a separate login interface? If a separate login interface will be used, would I need Firebase Admin SDK and Cloud Functions (the problem here is that we do not have a credit card for the Cloud functions)?

Solution

  • I am not sure how you are executing the QR Code logic for both admin and users and fetching all these details. Nonetheless, I would like to suggest an approach that you can follow. You can set your authentication based on role and create multiple routes for your application using React Router for Firebase.

    • For instance, a user should be able to visit a public landing page, and also use sign up and sign in pages to enter the application as an authenticated user. If a user is authenticated, it is possible to visit protected pages like account or admin pages whereas the latter is only accessible by authenticated users with an admin role.
    • There is no reason to show a non authenticated user the account or home page in the first place, because these are the places where a user accesses sensitive information. In this section, you will implement a protection for these routes called authorization. The protection is a broad-grained authorization, which checks for authenticated users. If none is present, it redirects from a protected to a public route; else, it will do nothing. The condition is defined as:

    const condition = authUser => authUser != null; // short version
    const condition = authUser => !!authUser;
    In contrast, a more fine-grained authorization could be a role-based or permission-based authorization
    // role-based authorization
    const condition = authUser => authUser.role === 'ADMIN';
    // permission-based authorization
    const condition = authUser => authUser.permissions.canEditAccount;

    The real authorization logic happens in the componentDidMount() lifecycle method. Like the withAuthentication() higher-order component, it uses the Firebase listener to trigger a callback function every time the authenticated user changes. The authenticated user is either an authUser object or null.. If the authorization fails, for instance because the authenticated user is null, the higher-order component redirects to the sign in page. If it doesn't fail, the higher-order component does nothing and renders the passed component (e.g. home page, account page). You can check this tutorial and get an idea of the approach I was mentioning.

    Just a reminder : While Firebase Realtime Database can be used on the free plan, Cloud Firestore is charged by usage. That's why you can set monthly quotas and budget alerts. You can always see the pricing plan, and adjust it, in the bottom left corner of your Firebase project's dashboard. Also yes Cloud Functions still has a monthly free allowance that's documented in the pricing page. But you will have to provide a credit card and be on a billing plan in order to use it. You will be responsible for paying for any monthly overage. But I don’t think you will need Cloud functions for that matter, just some decent db rules to protect your database and the authentication of your application based on role and routes using React Router for Firebase should be good enough.