Press "Enter" to skip to content

FIREBASE: integrate ADMIN SDK with NodeJS back-end API

In our first article about Firebase here I described how to create Firebase account, how to add it to our project and how to deploy whole project on Firebase hosting.

In my second article about Firebase I described how to integrate Firebase user authentication service.

So – two previous articles are about integration or Front-end – JavaScript application (in my case it was VueJS app created with Vue CLI).

In this article we will dive deeper and we will integrate our back-end API based on NodeJS (ExpressJS) with Firebase.

You must understand that you can use most of the Firebase services both in front-end and back-end of your application. In my example – I have integrated in my app with user authentication service. So procedure is as following:

  1. User opens my application (front-end) and can register a new account and login there. Here only app front-end is integrated with Firebase auth service.
  2. But we can check only from front-end that user is logged in and give access to some features only on client site.
  3. In real life – almost always – there is also app back-end in place. So with Firebase authentication service we can pass user TOKEN from front-end to our back-end, verify directly with Firebase if token is still valid and give access to some protected NodeJS API endpoints.
  4. But in here the back-end <-> Firebase connection is called FIREBASE ADMIN SDK.
  5. Summarizing – User login in app front-end, wants to open some protected functionality – user token is sent to back-end, back-end verify that with Firebase Admin SDK and give or refuse access to protected functionality.

You can find whole front-end app project files HERE ON GITLAB.

How to do that? Let’s check it step by step:

  1. In your NodeJS API application directory write down:
    npm install firebase-admin --save
  2. Open Firebase console and go:
    > Settings > Service Accounts:
    https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk
    Then we should choose the project, next proceed as in the picture:

    Integrate Firebase Admin SDK with NodeJS back-end API
    Integrate Firebase Admin SDK with NodeJS back-end API
  3. When we click “Generate new private key”, we have to save this JSON as a serviceAccountKey.json file. REMEMBER, IT IS A PERSONAL DATA FILE, WE SHOULD NOT KEEP IT PUBLIC!
  4. Then we create new file for example firebase.ts. To this file we copy the content (from above screenshoot), we can also adapt the content to the conditions of our project:
    import * as admin from 'firebase-admin';
     
    const serviceAccount = require("./key/serviceAccountKey.json");
     
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
      databaseURL: "https://YOUR-APP-ADDRESS-firebaseio.com"
    });
    
  5. Then we can use all methods of Firebase, look into the documentation, position ADMIN, for example authentication: https://firebase.google.com/docs/auth/admin and verifying tokens in NodeJS back-end: https://firebase.google.com/docs/auth/admin/verify-id-tokens
  6. We add the code responsible for data verification to the firebase.ts file and export it from the module. In this way, if the token is positively authorized, on the created promise we start resolve with the data received from the Firebase enquiry. If the authorization fails, we run the reject with error content.
    export const verifyIdToken = (idToken: string): Promise<string> => {
      return new Promise(async (resolve, reject) => {
        try {
          const decodedToken = await admin.auth().verifyIdToken(idToken);
          resolve(decodedToken.uid);
        } catch (err) {
          reject(err);
        }
      });
    }
    
  7. After the import into the file from API, for example index.ts, we run it as async/await/promise.then, e.g. If it is successfully resolved promise, we perform given request. Unless it is resolved, we return 401 and error content.
    import * as firebase from './firebase'
    …
    try {
        await firebase.verifyIdToken(req.query.idToken);
        res.send(products.productsList);
        next();
      } catch (err) {
        res.statusCode = 401;
        res.send(err);
        next();
      }
    

     

And now we can check user access to our back-end NodeJS protected endpoints. The Firebase user authentication service is really great because this is very sensitive functionality which we do not need to write by ourselves – the whole protection of user rely on Firebase, we can take it in use and take benefits from that without huge responsibility of hosting in our database user data. Of course we must protect data of currently logged in user, but this is much easier that writing whole Auth 2.0 based on JWT by ourselves.

THE END 🙂