Atlas
MongoDB Developer Center
chevron-right
Developer Topics
chevron-right
Products
chevron-right
Atlas
chevron-right

Bringing your data to your Wrist with the MongoDB Data API and Fitbit

John PagePublished Jan 12, 2022 • Updated May 19, 2022
AtlasData APIJavaScript
facebook icontwitter iconlinkedin icon
random alt
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
I use my Fitbit Versa smartwatch constantly, not only to tell the time and count my steps but to bring other information I might want to check up on right to my wrist. A couple of years ago, I built a custom watch face to do this but as my information preferences change, I need to modify the watch face. This time I decided to try a watch face that would dynamically adapt what it showed based on the contents of a document in MongoDB Atlas. That way, I could use triggers and the whole MongoDB Realm environment to gather and filter data for display rather than modifying the watch code.
There are probably some folks reading this thinking, "I have an Apple watch? Will this cover Apple watches?" The answer, strictly speaking, is no. I like the six-day battery life and super easy, Javascript-based, online development environment you get with a Fitbit watch, and you cannot use an Apple watch with my Android phone. Fitbit works with both. But, I'm sure if you did want to write a custom face for your Apple Watch, then the Data API would help you do that too.
The
MongoDB Atlas Data API i
s an HTTPS-based API that allows us to read and write data in Atlas, where a MongoDB driver library is either not available or not desirable. In this article, we will see how to call the Data API from a smartwatch application to retrieve a document that contains data to display. We will also dynamically update that document using scheduled triggers in Atlas.

Prerequisites

This is not a complete step-by-step tutorial, but if you wish to work through the process I followed yourself, you will need to create an account at
studio.fitbit.com
. You do not need to own a Fitbit device as you can use the simulator. If you do want a device, then Fitbit has them on sale at between $130 and $199 in January 2022, which is good for a fully fledged smartwatch that can make calls and run Alexa or Google assistant. I personally have a Versa 3 but for this, any Fitbit smartwatch will work.
You will also need an Atlas Cluster for which you have enabled the Data API, and our endpoint URL and API Key. You can learn how to get these in this
article
or this
video
, if you do not have them already.

Getting Started with Fitbit Development

Regular Fitbit developers swear by the
command line interface
and using Visual Studio code to develop. I think if I was developing regularly or professionally, I'd go down that route too. I'm not developing professionally, though. I'm creating a personal watchface for my own use and explicitly trying to make one I can modify without having to do any further development for the watch itself.
Fitbit provides an excellent browser-based development experience at
studio.fitbit.com
. This allows you to create watch faces (Known as clock faces, for some reason) as well as apps for the watch without needing to install any local tooling. There is also a Fitbit Simulator you can use instead of a physical watch, that you do need to install locally, but it's very easy to do so.
It doesn't make sense to repeat or rewrite the excellent introduction tutorials that Fitbit itself provides. So, if you want to work through this yourself either with a Fitbit of you own or with the simulator, you should start by reading Fitbit’s own "
Getting Started
" page. This will take you to your first watch face in 20 minutes or less.
As of January 2022, Fitbit has a small issue with the simulator not appearing in the IDE as a device. This is due to an expired Certificate Authority Certificate in the local binary. You can fix this by following the
instructions in the Fitbit Forum
to copy a new certificate into the Windows or Mac app directory .
At this point, you should have a watch face, either a rather ugly, red face like this
or something more attractive like this

Displaying Core Stats from the Fitbit

This is where I started my development and the first thing I need is the four locally-sourced values I want to see on my write at all times: time, date, daily step count, and the watch battery level. To do that, I changed the SVG-based layout, the styling CSS, and the Javascript index.html for the same clock face in the IDE to the following.
index.view
style.css
index.js
The* index.view* file defines the elements of the face where an SVG is the equivalent of an HTML div when used in a Fitbit application, as everything is drawn as scalable vector graphics. The* style.css *file styles and positions the elements, one in each corner—larger font used at the top.
The* index.js *file above defines what to do on the ontick event, and configures it to be called once a minute. This then sets the date, time, steps, and battery level of the various elements. Even if you have never programmed a Fitbit before, this should be familiar syntax if you have used any Javascript and HTML.
To test this, I need to select the phone Simulator and device Fitbit Versa 3 Simulator from the dropdowns at the top and click Run to see my simple but on-point watch face.

Dynamically Changing Layout on a Fitbit

I want to be able to fetch a Javascript document from the server and render whatever keys and values in it on my watch face. I could simply show a JSON document in a text box but that is too geeky even for me. So, my plan was to dynamically add elements to the SVG for keys and values.
It turns out that you cannot dynamically construct layout SVG. (Fitbits have tiny CPUs and RAM and pre-allocate RAM for the face elements. This makes sense when you are trying to build something that sips power. The Javascript is also compiled to machine code rather than interpreted on the watch.) The trick, therefore, was to precreate a number of empty elements and then move and populate them how I want to render the face. To do this, I changed index.view to the following. Watches are physically small, so I am assuming eight items of data at a time will be the most I can have without them being too small to read.
index.view
style.css (Additions)
I then added an extra function to index.js to render a Javascript object by setting and moving these text elements according to how much data I was displaying.
index.js (Additions)
Passing this a fixed Javascript object for testing, I get the following face.

Fetching Documents from Atlas with the Data API

The next step is to grab the required information from MongoDB Atlas to tell us what to display.
Fitbit watches do not run a TCP stack or connect directly to the internet as this would use too much power. Instead, they allow you to define the code of a “companion” application that runs in a Javascript sandbox on your phone and provide a simple lightweight way for either the companion or the watch to send a message to the other.
To retrieve data from Atlas, we are going to have the watch request an update from the companion either once a minute or whenever we look at the face (Fitbit detects this). The companion app will send that update to the face once it receives it from Atlas.
The companion app can include some simple node.js modules but is a fairly restricted sandbox and therefore, it is not possible to use the MongoDB node.js driver. Fortunately, we now have the MongoBD Atlas Data API which allows us to interact with data in MongoDB Atlas using an HTTPS call and an API key. Calls to an HTTPS service are very simple when using the Fitbit companion API.
You create a companion application by adding a directory called “companion” and a file called “index.js” in it. The code for my companion application is as follows.
companion/index.js
As this is my personal watch face and I'm not publishing it to the Fitbit store, I have hard coded my API key and endpoint for simplicity. If this was to be generic, you would need to look into the application configuration/preferences options to allow a user to supply an API key and URL after installing the face.
To have the face connect to the companion application, we need to add the following lines to the index.js for the watch face. This just adds error handling and what to do on receipt of a message. The connection will be opened when we send a message to it.
index.js (Additions)
We also want to modify the ontick function to request an update from the companion. In my example, I can send an empty string as the companion has only a single job to do.
index.js (Change)

Using Atlas Triggers to Update the Fitbit Watch Face

This is all fine—except we are asking the companion to fetch us a document that doesn't yet exist, so no data will be shown on the watch face. We need a way to populate our dynamic data. For me, the best way to do this was to use
scheduled triggers
in MongoDB Atlas to update the document we are showing on the watch face.
Scheduled triggers will run on the MongoDB Realm’s hosted servers and allow you to write Javascript code that can include most NPM libraries. Here is a very simple example that I used to fetch the MongoBD stock price and store it so it is displayed on my Fitbit.
You can access triggers from the menu on the left in Atlas.
Create a new trigger and complete the form as follows, selecting a scheduled trigger.
Now select function and fill in the code to run on the schedule. This code retrieves the MongoDB stock price and writes it to a document in a collection called "fitbit.data." It updates an existing record or, thanks to the {upsert}, creates a new document. This means we do not need to pre-create the document that contains the data for our watch.
Run the function to verify that it succeeds and watch the watch face update. (It may take up to one minute.) Now you have a watch face being updated by a server side process.

Conclusion

It's not the prettiest watch face in the world and I'm sure I'll spend some time tinkering with it to make it a little more attractive, but that should be just changing CSS and I'm sure most of my readers are better than me at doing that. I can also spend time working out what things matter to me to display on it, but adding them is now as simple as writing a MongoDB trigger, and I don't need to change the watch face itself.
Have fun with this. Next time, we are back to serious, enterprise-grade uses for the MongoDB Data API.

Copy Link
facebook icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Podcast
Atlas 5-Year Anniversary Podcast Series Episode 1 - Onramp to Atlas

May 16, 2022
Quickstart
Using the Atlas Data Api with Google Apps Script

May 24, 2022
Tutorial
Tutorial: Build a Movie Search Engine Using Atlas Full-Text Search in 10 Minutes

May 12, 2022
Tutorial
MongoDB Atlas Data Lake Tutorial: Federated Queries and $out to AWS S3

Jun 07, 2022
Table of Contents