# Authenticate Zoho CRM in serverless - Firebase implementation

> Generate an access token using OAuth2 and begin utilizing API 2.0 in a serverless environment.

BlowStack blog, published 2020-12-08, updated 2022-10-15, 10 min read. Page: https://blowstack.com/blog/authenticate-zoho-crm-in-serverless-firebase-implementation

This serverless Zoho CRM authentication guide is tailored for Firebase Functions using Node.js. By the end of this article, you will learn how to leverage serverless functions for authentication using OAuth 2.0, as well as how to make straightforward calls using the Node.js SDK.

To carry out authentication, you must activate the Blaze plan in your Firebase account. Additionally, we provide a straightforward solution for obtaining [the Blaze plan at no cost](https://blowstack.com/blog/what-is-firebase-and-how-to-use-it-with-web-apps#blaze-plan-get-it-for-free-and-avoid-bankruptcy).

## **Prepare environment for Firebase functions**

If you're already versed in creating Firebase functions, you might want to skip ahead to the subsequent section.

Start by finding a suitable location on your system to set up a new project for Firebase functions. Following that, install the necessary official Firebase tools globally with:

```plaintext
npm install -g firebase-tools
```

Then, initiate a Firebase project using the newly installed tools:

```plaintext
firebase init
```

When prompted, select the "Functions: Configure and deploy Cloud Functions" option by pressing space.

![](https://storage.googleapis.com/blowstack-d3322.appspot.com/images/blog/posts/firebase-init.jpg)

Firebase initiate a project

Firebase will then guide you through initializing a project. You can either select an existing project (if your app is already hosted on Firebase, it's advisable to choose that project, though it's not mandatory) or create a new one. You will be asked to log in for authentication. Upon successful login, your Firebase project will be set up.

Open the project in your IDE; the core directory is named `**functions**`, which is where you'll be working to create new functions. If using an IDE console, switch to this directory. Otherwise, remember to execute any console command from within this directory.

## **Install Node.js SDK for Zoho CRM**

Installing the official Zoho SDK is beneficial for handling authentication and API calls. Install the SDK in the `**functions**` directory:

```plaintext
npm install zcrmsdk
```

Then, in the `**index.js**` file, require this module and add the configuration object:

```javascript
// functions/index.js

const functions = require('firebase-functions');
const ZCRMRestClient = require('zcrmsdk');

const config = {
  "client_id": "your_client_id_here",
  "client_secret": "your_client_secret_here",
  "redirect_url": "http://your_redirect_url_here",
  "user_identifier": "your_user_identifier_here",
  "tokenmanagement": "zohoAuth"
};
```

Replace the placeholders in the config object with your actual data. If you're unsure where to find these values, refer to my previous post on [Zoho CRM authentication in Node.js](https://blowstack.com/blog/authenticate-zoho-crm-in-node_js) for guidance.

The `**tokenmanagement**` value is crucial; it should reference an object that implements three functions required by the SDK for token management. Next, you'll create these functions and encapsulate them into a Node module.

## **Create oauth.js file**

Inside the `**functions**` directory, create a subdirectory, for example, `**zohoAuth**`, and within it, create a file named `**oauth.js**` with the following content:

```javascript
// functions/zohoAuth/oauth.js

let file_persistence = {};

const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.firestore();

file_persistence.saveOAuthTokens = function (tokenobject) {
    return new Promise(function (resolve, reject) {
        let tokens = {}

        db.collection('zoho').doc('tokens').update({
            access_token: tokenobject.access_token,
            expires_in: tokenobject.expires_in,
            refresh_token: tokenobject.refresh_token,
        })
            // eslint-disable-next-line promise/always-return
            .then(function (docRef) {
                resolve()
            })
            .catch(function (error) {
                console.error("Error adding document: ", error);

            })
    })
}

file_persistence.getOAuthTokens = function (user_identifier) {
    return new Promise(function (resolve, reject) {
        let tokens = {}

        // eslint-disable-next-line promise/always-return
        db.collection('zoho').doc('tokens').get().then((snapshot) => {
            let data = snapshot.data()
            tokens.access_token = data.access_token
            tokens.refresh_token = data.refresh_token
            tokens.expires_in = data.expires_in
            resolve(tokens)
        }).catch((err) => {
            console.log(err)
            resolve()
        })

    })
}

file_persistence.updateOAuthTokens = function (tokenobject) {
    return new Promise(function (resolve, reject) {

        db.collection('zoho').doc('tokens').update({
            access_token: tokenobject.access_token,
            expires_in: tokenobject.expires_in,
        })
            // eslint-disable-next-line promise/always-return
            .then(function (docRef) {
                resolve()
            })
            .catch(function (error) {
                console.error("Error adding document: ", error);

            })
    })
}

module.exports = file_persistence;
```

This implementation leverages the Firebase database for token management, with no need for separate authentication values as it operates within Firebase servers.

Change to the `**zohoAuth**` directory and generate a `**package.json**` file:

```plaintext
npm init -y
```

Ensure the `**package.json**` file reflects `**zohoAuth**` as the name value. Then, return to the `**functions**` directory and create a local Node module from the `**zohoAuth**` folder:

```plaintext
npm install --save ./zohoAuth
```

Your configuration object now references an existing module. Should you need to modify the functions in the future, do so within the `**zohoAuth**` directory inside the `**functions**` folder, not in the `**node_modules**` directory.

## **Create a new collection**

The module you created references a non-existent database document and collection. To rectify this, navigate to the Firebase console, access the database tab, and create a new collection named `**zoho**` with a document named `**tokens**`. This document should have three empty fields for `**access_token**`, `**expires_in**`, and `**refresh_token**`.

![](https://storage.googleapis.com/blowstack-d3322.appspot.com/images/blog/posts/firestore-zoho-tokens.jpg)

Firestore Zoho tokens collection

Adjust Firestore and Firebase rules as necessary to ensure security and proper access management.

![](https://storage.googleapis.com/blowstack-d3322.appspot.com/images/blog/posts/Firestore-rules-menu.jpg)

Firebase rules menu

![](https://storage.googleapis.com/blowstack-d3322.appspot.com/images/blog/posts/firestore-tokens-permission-rules.jpg)

Firebase Firestore permission rules for tokens

## **Create a function for serverless authentication**

It's time to consolidate everything into a Firebase function that generates access tokens for us. Navigate to the `**index.js**` file and insert the following code:

```javascript
// Add this at the top of your index.js file
const functions = require('firebase-functions');
const ZCRMRestClient = require('zcrmsdk');

// Your existing configuration object
// Ensure your config object is defined above this function

exports.renderTokens = functions.https.onRequest((request, response) => {
    const grant_token = request.query.grant_token;

    ZCRMRestClient.initialize(config).then(() => {
        ZCRMRestClient.generateAuthTokens(config.user_identifier, grant_token).then((auth_response) => {
            console.log("Access token: " + auth_response.access_token);
            console.log("Refresh token: " + auth_response.refresh_token);
            console.log("Expires in: " + auth_response.expires_in);
            response.send('Tokens generated successfully');
        }).catch((error) => {
            console.error(error);
            response.status(500).send('Error generating tokens');
        });
    }).catch((error) => {
        console.error(error);
        response.status(500).send('Error initializing ZCRMRestClient');
    });
});
```

This implementation straightforwardly uses the SDK to generate tokens. The `**zohoAuth**` functions ensure the token management process is fully covered. Test this function using tools like Postman to verify token generation. Before testing, deploy your Firebase function using:

```javascript
firebase deploy
```

After deployment, you'll receive a Function URL. Use this URL in Postman to test token generation. Remember to generate a grant token beforehand. If you're unfamiliar with this process, please revisit the previous article on [Zoho CRM Node.js implementation](https://blowstack.com/blog/authenticate-zoho-crm-in-node_js) for guidance. In Postman, make a request and include a parameter named `**grant_token**` with your previously generated grant token as its value. It may take some time for the tokens to generate, so check back after a few minutes to see if the database document has been updated. Proceed to test the API using an example call if the document has been updated.

![](https://storage.googleapis.com/blowstack-d3322.appspot.com/images/blog/posts/Postman-Zoho-CRM-serverless-token-generation.jpg)

Postman Zoho CRM Serveless token generation

## **Create a lead function**

Next, let's create another function to verify our service's ability to insert data into Zoho CRM. Add the following code to your `**index.js**` file:

```javascript
// functions/index.js

...

exports.lead = functions.https.onRequest((request, response) => {
    ZCRMRestClient.initialize(config).then(() => {
        let input = {
            module: 'Leads',
            body: {
                "data": [{
                    "First_Name": 'First Name Example',
                    "Last_Name": 'Last Name Example',
                    "Email": 'example@example.com',
                    "Description": 'Sample description',
                }]
            }
        };

        ZCRMRestClient.API.MODULES.post(input).then((apiResponse) => {
            console.log(apiResponse);
            response.send('Lead created successfully');
        }).catch((error) => {
            console.error(error);
            response.status(500).send('Error creating lead');
        });
    }).catch((error) => {
        console.error(error);
        response.status(500).send('Error initializing ZCRMRestClient for lead creation');
    });
});
```

Deploy your code to Firebase and use the URL in Postman to call the function. Later, check your Zoho CRM account to confirm the lead's insertion.

This guidance helps you understand how to authenticate and make API calls to Zoho CRM using a serverless environment, setting a foundation for expanding functionality with additional functions. Remember, Postman doesn't enforce CORS by default, so your calls won't be blocked, but this might not be the case with your app. In such instances, ensure to pass the correct headers to allow requests from the Firebase domain.

---

BlowStack: AWS practice exams and courses, https://blowstack.com/practice-exams
