August 31, 2015

Firebase + Pebble

The first time I saw someone using a Pebble Smartwatch and Firebase together was at HackIllinois a couple years ago. A team decided they could use a Pebble + Firebase's realtime capabilities to make an app that let them cheat in class. I thought this was awesome and I wanted to make something just as cool. However, until recently I've been too cheap to buy a Pebble.

That all changed last week when I picked up my Pebble Time. This is a wonderful watch that is as useful as it is whimsical. However, it just wasn't fire-y enough for me.

I did some quick googling and didn't find any complete resources on how to set up a Pebble to play nicely with Firebase, so here is what you need to do.

If you don't feel like playing along, you can just go clone the example Pebblebase repo for a complete Firebase/Pebble example.

1. Choose between the CloudPebble IDE and Native SDKs

We'll be developing our Firebase/Pebble app using PebbleJS. This is a small C app which runs JavaScript in a browser-like environment (not NodeJS-like, this is important later). You can either use the CloudPebble IDE which requires no installing to get up and running or you can use the Native SDK which requires downloading and installing a few things. They will both let you build the same PebbleJS apps, however the Native SDK is dramatically faster to use.

2. Set up a PebbleJS project

If you're using CloudPebble, you just need to hit the "Create" button and it will automatically set up a new PebbleJS project. If you're using the Native SDK, you'll need to clone the PebbleJS repo then navigate to src/js/app.js. You can ignore the rest of the repo, you won't need it.

3. Get the Firebase SDK

This is the most confusing part of the process. If you look at the app.js file provided by the PebbleJS repo, you'll see it uses require(...) to import dependencies. This might trick you into thinking that our scripts will be running in a NodeJS-like environment, but this isn't true. This JavaScript will actually be running in a headless browser on your phone. That means that the NodeJS Firebase SDK will not work. You'll need to go to the Firebase Web SDK page and click the big Download button on the top to get the SDK that works in browsers.

Once you're looking at the latest Firebase SDK, you can either download the file and put it in the same folder as your app.js or copy the contents of the file and click Add New in CloudPebble to add a new JavaScript file. Either way, we'll call it firebase.js.

4. Import Firebase.js into App.js

This is where things get just a little bit silly. If you look at lines 7-8 of app.js you'll see something like this...

var UI = require('ui');
var Vector2 = require('vector2');

If you've ever used the NodeJS Firebase SDK, your instinct will be to do this...

var UI = require('ui');
var Vector2 = require('vector2');
var Firebase = require('firebase');

However, as you see by my comment, this does not work. It doesn't work because the Firebase Web SDK isn't packaged as a module, meaning it doesn't export anything, it simply exposes Firebase on the global/window namespace. If you try to new Firebase(...) using the require above, you'll get an error because Firebase will be undefined.

To get around this, we need to simply change our require to look like...

var UI = require('ui');
var Vector2 = require('vector2');

Notice the slight difference. Before we were attempting to assign Firebase to whatever our Firebase JS file was exporting, but since it exported nothing, it would override Firebase to be undefined. However, if we remove the var Firebase = bits, we allow the script to be imported, executed, and to globally expose Firebase like we want.

It's not important that you understand that explanation. It's just important that you don't try to use the first example.

If you're using CloudPebble, you'll also need to force the Firebase client into Websocket mode by adding this line immediately after require('firebase'). If you're using PebbleJS, you can skip this step.


5. Make your Firebase/Pebble app!

There you go! You can now use your Firebase object just like you would in the browser. That means code like...

var ref = new Firebase(YOUR_FIREBASE);
ref.on('value', function (snapshot) {

...will work exactly like you would expect.

6. Next Steps

I've put together a small Firebase/Pebble project called Pebblebase, which demonstrates reading, writing, and getting realtime updates from Firebase on your Pebble. I'd suggest reading through the app.js file for a more complete example.

PS. If you work at Pebble...

I scratched the bezel of my Pebble Time while writing this blog post, so if you wanted to be super nice and send me a new, non-scratched one, we'd be best friends forever. I feel really dumb, cause I've literally had it six days.