Use JSforce and Firebase Functions to query Salesforce data
So you want to get some data from Salesforce, quickly, cheaply and without managing any servers? You’re in luck! By using JSforce and Firebase Cloud Functions you can get up and running in no time!
1.0 Things you will need…
1.1 A Salesforce user account (you’ll use this as a service account)
First of all you will need a Salesforce user account with sufficient persmissions to query the data you need. If you’re the Salesforce admin then this shouldn’t be a problem, otherwise just find your Salesforce admin and ask him nicely. You will also need a password for this account, and depending on your Salesforce environment, you may need a security key too.
1.2 A Salesforce SOQL query
You will need to get the right SOQL query to return the data you need. This a a SQL like query that is used to query data in Salesforce. Workbench is a great tool to test out SOQL queries and make sure that you are getting the right data. A SOQL query looks something like:
SELECT Id FROM Contact WHERE Name LIKE ‘A%’ AND MailingCity = ‘California’
1.3 Node.js and NPM
You’re going to need to install Node.js and npm on your local machine. Check which version of Node.js Firebase presently supports here, then make sure to use this version. At the time of writing, Firebase recommends Node v6.14.0. I use NVM (node version manager) to change versions when I need to. Note that I am running Ubuntu (it just makes this sort of stuff much easier imo) so any CLI commands written in this post may not not necessarily work on Windows or Mac.
1.4 A code editor
I use VS Code, but you can use whatever you’re comfortable with.
1.5 A Firebase project
Head over to the Firebase Console to create a new project named jsforce-functions. It’s a pretty straightforward process, just follow your nose. You will need a Google account.
2.0 Setting up Firebase Functions
Firebase has some good documentation on getting set up with Functions here. What it boils down to is installing the Firebase CLI and initialising Firebase Functions within your project’s folder, so let me summarise here:
2.1. Install the FIrebase CLI globally with npm:
npm install -g firebase-tools
2.2 Create a folder to house your project on your local machine:
2.3 Change directory to your project:
2.4 Log into Firebase from the CLI:
2.5 Initialise Firebase Functions within your project:
firebase init functions
2.6 You will be asked to select a project so choose the one you created just before:
2.8 You will be asked if you want to use ESLint. Don’t, we are just testing things out here. Press n:
? Do you want to use ESLint to catch probable bugs and enfore style? (Y/n)
2.9 You will be asked if you want to install dependencies with npm. Press Y:
Do you want to install dependencies with npm now? (Y/n)
2.10 If everything worked out alright, open your project folder up in VS Code and you should now have a project structure like this:
3.0 Write some code!
3.1 Setting up the project structure
Within our project, jsforce-functions/functions/index.js is the entry point to our functions. We could write a Cloud Function directly in here, but this would get messy and hard to maintain if our project grows. Instead we are going to create some subfolders and keep things more organised. We are going to avoid writing long functions that do lots of things and instead write a number of smaller functions that are easier to understand and maintain.
It is worth noting that at the time of writing, Firebase recommends using Node v6.14.0 with Firebase Functions. This means that we can’t yet use async / await and other newer JS syntax and features. It’s no biggie though, we can just use good old Promises.
Within the functions folder, create 2 new folders called jsforce-functions/functions/fetch-data and jsforce-functions/functions/display-data. Within jsforce-functions/functions/fetch-data, create a new file called jsforce-functions/functions/sf-auth. In this file we will create a function to handle authentication with Salesforce.
3.2 Authenticating with Salesforce
In order to query Salesforce we need to authenticate. To do this we will use the JSforce library, so open up a terminal, change your directory to jsforce-functions/functions and install JSforce by running:
sudo npm install -save jsforce
Your file jsforce-functions/functions/package.json should now have a new entry for JSforce:
Next, head back to jsforce-functions/functions/fetch-data/sf-auth.js. We are going to write the function that will handle authentication and return a promise containing the conn object that we will use to form our Salesforce query. Remember earlier we got our Salesforce credentials sorted? Now is the time to use them.
Within jsforce-functions/functions/fetch-data/sf-auth.js you will need to change some variables:
- username: This is the username for the Salesforce account we sorted out earlier
- password: This is either the password to your Salesforce account or the password + the security key in one word without any spaces. If in doubt, speak to your Salesforce admin as I belive this reuqirement varies between Salesforce environments.
- loginUrl: This is probably the URL you use to log into the Salesforce portal, however if you have load balancing in place then this may not be the case. If in doubt, speak to your Salesforce admin.
3.3 Querying Salesforce
Next up we need to write a function to query Salesforce. Create a new file jsforce-functions/functions/fetch-data/sf-query.js. Within this file you will need to change a variable:
- queryString: This is the SOQL query we prepared earlier.
3.4 Handling Responses
We are well on our way to having our own API, so next we need to create a way of handling responses.
Create a new file jsforce-functions/functions/fetch-data/send-res.js.
3.5 Tying our functions together
Our Cloud Function now has the individual functions to authenticate with Salesforce, make a Salesforce query and send a response to the front end. Next we just need to tie these functions together to form our API. Create a new file jsforce-functions/functions/display-data/load.js.
3.6 Update index.js
The entry point to our Firebase Functions is jsforce-functions/functions/index.js. We are going to create a new function in here that will point to jsforce-functions/functions/display-data/load.js. On deployment, Firebase Cloud Functions reads any functions declared within this file and automatically creates HTTP endpoints which trigger these functions to run. This means that you can simply load a URL to trigger your function.
4.0 Run your Firebase Function!
4.1 Serve your function locally
One of my favorite features of Firebase Functions is the ability to serve your functions locally. This makes debugging and troubleshooting a whole lot easier than having to deploy your function to the cloud and deal with logs from there. To do this, open up a terminal, change directory to jsforce-functions/functions and run:
sudo firebase serve
This will give you a url:
Just open that up in your browser and your function will run! If this doesn’t work the first time just check your console to see where things are falling over.
4.2 Deploy your function to the cloud
Once everything is working as desired, you can deploy your function to the cloud so that it is available anywhere. Before doing this, it is extremely important that you stop and think about what data you are allowing to be exposed publicly. This tutorial has not shown any authentication on the Cloud Functions, so anyone with the URL could load whatever Salesforce data your SOQL query gives access to. You need to make sure that your hard coded query does not expose any sensitive information, or at the very least anything that is not already publicly available. You have been warned!
Once you are confident that the data you are making publicly available is OK to be public, open up your terminal and run:
sudo firebase deploy
This should give you a URL that looks something like: