I had an interesting discussion about how skateboard trucks worked. We wanted to understand how changing hanger angles affected how the board turned. I ended up building a visual simulator.

Click here for Simulator

Click here for Source Code (JavaScript and Three.js)

Note, to operate the board, set hanger axis angle and rake, then adjust board tilt dynamically. Note at high rake angles, things get jumpy. Need a bit more coding to ensure the dynamics are smooth. Any coding volunteers? Contact us!

A package manager is a tool that helps a developer navigate the complicated space. Where would we possible be in the JavaScript world without Node Package Manager (NPM) with thousands of libraries and tools available with a few key strokes. The folks at Microsoft are attempting to bring the same utility to the C/C++ world, although because of the nature of the language, admittedly this is a much steeper hill to climb. Because of the intricacies of the different compilers and operating systems plus the unique compilation needs of each library, this is a really difficult thing to manage. I commend the effort.

With that said, this can be a frustrating tool to use. Essentially you install VCPKG, the package manager tool, to a known location in your system. Then, you add the specific library system to that. The VCPKG goes and gets that library package source code and compiles it into the VCPKG location. Generally that package compilation will include specific instructions for use of that library.

Link to the VCPKG repo is here…

What is the expectation here?

  • VCPKG installs consistently.
  • Add-in libraries install consistently and successfully in Windows, Linux, MacOS
  • What ever instructions the installer prints out for a given library, function as intended on the installed OS.

The good news?

  • Some pretty good people seem to be working hard on this project.
  • If you are using Visual Studio on Windows, the global installation tooling works seamlessly.   Its like magic.  Installed libraries just work, without extra configuration setup.
  • For other operating systems you may have to use CMake instructions.  Generally the VCPKG displays the exactly nomenclature to add to cmakelists.txt

The bad news?

  • There are a whole lot of open issues in the VCPKG repo (1300+).
  • Not every repo prints the correct cmake instructions for that package.
  • There is not a clear “How to Help” design document to enable the open source supporters to assist in closing out that large number of open issues.

So I often type web addresses directly into the URL line on my browser. Today I did that, but erroneously included a misspelling. The site I wanted to go to was http://usaa.com, but instead I typed http://usaas.com And I got an odd response. It popped back with a spammy redirect address… I did this a few times. Once redirect ended up at to www.givemethisoffer.com , once to get1.mysecurify.com, and once to www.homeinsurancespecials.com. When I watch the process carefully, I can see the first redirect is going to searchiq.co

Uh oh. I must have a virus? So I do a whole lot of testing. I don’t directly find anything. So I do some more testing. Turns out somebody bought http://usaas.com and that site responds accordingly. Site just pushes out garbage and crap. Not sure if that is intentional, but that’s my guess. Total garbage stuff. What has the internet become? Site verified via https://gwhois.org Note: and on the chance that the site is legit and just got hacked, I did send an email off to the site owner / abuse contact informing them of same.

I’ve been developing applications for a long time. Using cookies was a concept I was vaguely aware of, but I never really focused on in the past. I ran into a dilemma that I just couldn’t get around. I’m working on site / responsive app protected via JSON (JavaScript Object Notation) Web Tokens for authentication and user identification. The site I’m working on is a single page web app in which the content is populated after authentication via AJAX calls. The site uses NodeJS, Express Generator and jQuery Mobile.

I want to add a route to the site that generates a server generated PDF report. To keep things simple, I wanted to do a GET request via link to a new tab. The trouble was figuring out a way to protect that page, without additional login and authentication. It turns out sending content via Cookies works pretty well.

Library used: cookie-parser. Whoa.. I never realized that library is included in Express Generator. Nothing extra to load, its already there. In my case, I set a cookie at the server in a response header after the initial authentication process. Did a bit of testing, and this is totally easy. The cookie is included in any subsequent server request including a simple < a href="./report" target="_blank">Create a PDF report... Obviously the target=”_blank” opens the link in a new tab. I did a whole lot of testing, and there just was no way to open a redirect to a new tab using a post request to generate a pdf file.

The other thing I wanted to understand was the use of the use of Cookies and signing. I did a bunch of testing, and here’s what I found:

  • In app.js, I set app.use(cookieParser('MY SECRET CODE'));
  • In my routes file, I set response.cookie("cookie_name" , 'this is my first cookie', {signed: true});
  • Open up my app in the browser, perform authentication, check cookies value using Chrome browser and Inspect dev tools.
  • There are two ways to do this: using Inspect –> Appplication Tab –> Cookies or in the browser console type document.cookie.
  • "cookie_name=s%3Athis%20is%20my%20first%20cookie.3Q8973HkDKE4vElmeYBGp%2FRnPAKnuePvhZoLSG8Gjpc"
  • Test a submit via link to new tab. Review data on the server. Sure enough, in the submitted request, I find a value “cookies”, but also a value for “signedCookies”.req.signedCookies {cookie_name: "this is my first cookie"}
  • But hang on a second. That cookie in the browser looks like something easy to fake out. Let’s try this and see what happens. I go back to the site in the browser. Clear out the cookies. Create a new fake cookie, a=b, using the generated hash observed above… document.cookie = "a=b.3Q8973HkDKE4vElmeYBGp%2FRnPAKnuePvhZoLSG8Gjpc"
  • Test link submit again. Carefully read the contents of the request object. cookies object shows a=b… BUT request.signedCookies is totally blank {}

And that means I can trust the system to identify somebody playing games with cookies, as long as I use request.signedCookies for my authentication work. This is pretty awesome.

And yes I did go back and create response.cookie("a" , 'b', {signed: true}); and the hash code is something totally different from previous.

I will say until I went through this testing I was not really aware of how easy this stuff really is. Note, I do have to commend the folks at Microsoft for the VS Code developer tool. That makes it so easy to step through server code and really understand request and response objects. Many thanks to all the folks supporting that tool.

Hmmm. There has been a lot of progress in producing high quality videos of totally manufactured (fake) content, using machine learning and lots of processing power. This can have really disastrous consequences in the wrong place and time. How do you identify fake content? Why using machine learning and lots of processing power, of course.

This reminds me of military design specifications in the recent past. Think Us versus Them (USA v. Russia) circa 1970 or so.

  • The bullet from our standard issue rifle has to be powerful enough to penetrate the helmet of our most likely enemy.
  • Our helmets have to be strong enough to prevent being pierced by the bullet from our likely enemy’s standard issue rifle

And guess what, our likely enemies have exactly the same requirements. Kind of a no win proposition…

I just finished up a new project. And as always, I like to learn new stuff, and roll that into the essence of the project as I go. Software development is really about learning new stuff. Change is constant (think about that for a moment..) The tools, the language, the techniques… there’s always something new coming along. Nobody programs in Cobol or Fortran with punchcards anymore. And nobody uses Visual Basic anymore either. ha. But I digress.

The project:
Its an information application for an unusual small business group. The group has a lot of personnel turnover, and communications among the team is critical. The application provides detailed job description task sheets, a phone directory for the working facility land lines, key references / users guides and a complete business group team directory complete with users photos, phone contact, text page and email references. Until now, the group has published an annual 30 page paper pocket guide. Ugh. Where’s the fun in that? Hey guys, everybody in your organization has a mobile cell phone, let’s use that. We really want to take advantage of mobile browser links href=”tel:+1…” and href=”sms:+1…” and href=”mailto:[email protected]” … Check out the attached screen shots of the phone directory. Included is a photo popup of each individual on demand.

Software Tools:
The basis for this application are the general tools used in the phone directory project.

  • jQuery Mobile for the presentation framework
  • Google Sheets API v.4 for team roster data store
  • Phone authentication via Google Firebase
  • AJAX calls to server to protect content
  • NodeJS with Express to serve both static content and API calls
  • Private Git repo at Gitlab

And of course, we’re going to stretch into some new arenas as well.

  • Google App Engine at Google Cloud for Nodejs hosting
  • Progressive Web App, primarily for native app like performance, and simple icon startup from users mobile phone.

Free Tier at Google cloud.

Google Cloud has a very generous free tier. The two tools I’m interested in are the Google App Engine and Google Compute Engine. A whole lot of what I’ve been doing lately (full stack) involves NodeJS / Express servers.

Google App Engine give the user:

  • 28 instance hours per day
  • 5 GB Cloud Storage
  • Shared memcache
  • 1000 search operations per day, 10 MB search indexing
  • 100 emails per day

Google Compute Engine free tier includes:

  • 1 f1-micro instance per month…
  • 30 GB-months HDD, 5 GB-months snapshot
  • etc…


Wow. Pretty cool. I ended up working with Google App Engine, Standard Environment. After all, my application has a customer base of less than 100 folks. Its not ever intended as a public facing website. The whole process worked pretty well, kinda sorta. Develop application on local host. Push to git repo. Login to Google Cloud, create project. Open App Engine, use GCloud command line interface, pull content from git repo. Push. Repeat. One note: I did initially have a terrible time updating the app engine content. Turns out that using the same Google project for multiple processes wasn’t clever. I had a job stopping error. Issue corrected by using one project for Google Firebase authentication, a second project for Google Sheets API v4 and a third project for Google App Engine. The tutorials on using the app engine from Google are pretty easy to understand.

Eventually updates are as easy as push to git on laptop, login to GCloud console, pull from git, then $ gcloud app deploy And hey, for anybody working on this stuff, I found this posting particularly helpful.

A couple of notes here. Using the free tier app engine may not be totally free. When you use the app engine, it deploys to the address “https://your-custom-application.appspot.com”. If you want to point a real URL to that location you will have to utilize the Google Cloud DNS service. I pursued that, the cost for minimal use would be only $0.60 / month. Because of our intended use case, the customer was perfectly happy with the provided free xxx.appspot.com url.

Next note: The App engine deployment is now totally SSH secured and free. Yowza. Many thanks Google! Why does that matter, really? This is the lead in to the next point.. Progressive Web Apps. One of the requirements there is SSH for everything.

Progressive Web App

I’ve been really interested in Progressive Web Apps (PWA) lately. Er. so what’s a web app, anyway?

  • Responsive – fits any form factor (Mobile / Tablet / Desktop)
  • Progressive - Work for every user, regardless of browser choice
  • Fast – Content served immediately from cache as appropriate
  • Reliable – Content served, even if user is offline
  • App-like - Feel like an app to the user with app-style homepage icon, interactions and navigation
  • Fresh - Always up-to-date thanks to the service worker update process.
  • Safe - Served via HTTPS to prevent snooping and ensure content hasn’t been tampered with
  • Linkable - Easily shared via a URL and do not require complex installation.

Special requirements include the requirement for HTTPS server, manifest file, service worker. The hardest thing to get there is the HTTPS server, but that’s done now, ThankYouGoogle! For a great example of a fun little Progressive Web app, check out the breaklock app at https://maxwellito.github.io/breaklock/ (git hub repo…)

In my case the whole PWA thing was a pretty good experience. We’re totally able to share the link and install the “app” as an icon on the users mobile phone home page. The app works well. We’re able to authenticate via Google Firebase, and protect content via AJAX call to server. And for most things this is pretty cool.

There is however one use case that is problematic. And that is what happens if the user goes offline? With a static website, this is a total no-brainer. All of the site’s components are stored in cache according to the manifest file. Per service worker code the cache content is immediately available for offline display.

But in our case, we’re deploying protected “dynamic” content via an AJAX call after the site is initially generated. Purely as a test, I thought it would be interesting to take a snapshot of the site after all the dynamic content is loaded, and store that in cache for display when the customer is offline. And that works great… on Android in the Chrome browser. But alas, totally fail on iOS mobile using Safari browser. Sigh. It seems Safari is not totally compliant with the browser specifications where access to cache is concerned. So.. I’m still working on this, trying to evaluate other options for “secure” offline access.

So I have an upcoming engineering project I’m working on… I’m trying to optimize an unusual powered propulsion system. I’m still working on a iOS / Android app to take detailed response data, but that’s another story. Right now I’m wondering how I’m going to do the statistical analysis for the testing when I begin to accumulate results. In the old days, I’ve used MiniTab. I can remember doing a whole lot of Gage R&R (Repeatability and Reproducibility) studies using that tool. A gage R&R study is really an Anova experiment which quantifies measurement error in a system. (Can you measure the thickness of a piece of paper using a wooden 12″ ruler? Of course not, etc…) MiniTab is an awesome software program, but holy moly is it expensive. Ouch. I’m wondering in this day and age is there is an open source alternative. And that’s what this posting is all about. I thought I’d build an experiment, and then attempt to analyse it with open source (read that as “free”) available software.

First off. I wanted an experiment that would be cheap and easy to do. Something that would be easy to understand. Something I (or anybody else) could test easily. And here’s what I came up with.

The Coin Drop Test

Drop a coin over a target, measure the distance from where it lands to the original target center. Obviously the goal is to land the coin as near to the target as possible.

Factors (each factor will have two levels):
Size of Coin (Dime or Quarter)
Height of drop (60″ or 30″)
Coin Release Orientation (horizontal or on edge)
Drop Hand Technique (finger/thumb or two fingers)
Target Surface (exercise mat vs deep pile carpet)
Distance from dropped coin to target center (C to C, inches)

The target is a piece of masking tape with a simple ‘X’ marked on it. For the target surface I used two different floor surfaces. My initial thought was that the deep pile carpet would preclude coins from bouncing too far away from the target, relative to the gym mat. I used two different easily available coins.. a quarter and a dime. I would have thought the heavier coin might travel less than the dime. Coin release orientation? My initial thought is that a coin dropped “flat” would remain close to the target. Obviously I knew there would be a lot of variation in the test results. I wanted to see where an experiment with lots of variability might go. I designed a full factorial experiment (2^5). In fact I ran each test four times for a total of 128 different tests. I was very carefully to randomize the tests. I used a simple random number generator, then re-sorted the test criteria in an XL sheet.

A couple of observations, notes: It would be best to decide before you start how accurate you want to be in your measurement. Round off to nearest inch? Nearest half inch? Or find a metric tape measure and measure in mm or cm? I started with nearest 1/4″ and that was probably not necessary. There was a lot of variability in the drop technique. Quite a few times, when using the two finger coin on edge method, when using a dime, the dime would stick to my fingers delaying the drop. Its funny, but by paying close attention to the test, you can sometimes spot unexpected trends, something you want to test in the next round of analysis.

And if you want to repeat or modify this experiment, here is the raw data! Do note, there are two columns there to aid in the randomization of the experimental design. Check out the columns original_order and random_order. Sort by one column or the other as necessary. In normal order it’s pretty easy to see how this full factorial experiment was setup.

And what makes the design of experiment / ANOVA so awesome, is you are not making predictions about results… but instead merely observing what happens. You may believe something is true, but this is a way to prove it (or not!) This is an experiment, used to help identify possible further opportunities to improve desired response. You may not know WHY factor A is better than factor B, but in observation something is measurably different between those two factors.

Analysis of Variance (ANOVA) — What is it?

To determine whether the difference in results is due to random chance or a statistically significant different process or factor, an ANOVA F-test is performed. The F-test is a tool used by statisticians to determine if different test observations occur because of randomization or a true difference in outputs based on which input (factor) is in use. The ANOVA F-test uses the null hypothesis that:

H(0): Coin size will have no significant effect on distance to target after coin drop.
H(0): Drop height will have no significant effect on distance to target after coin drop.
H(0): Coin release orientation will have no significant effect on distance to target after coin drop.
H(0): Drop hand/finger technique will have no significant effect on distance to target after coin drop.
H(0): Target surface will have no significant effect on distance to target after coin drop.

Analysis is performed on all the factors one at a time, and then in combination in a decent software package. You could program this yourself (in XL?) but its pretty easy to make a mistake, and not generally recommended. Note: for a nice discussion of the details in how such a program would work, I found this analysis pretty helpful:

And that lead me to start looking at open source software packages that might work.. I looked a whole lot of things. I discover a whole lot of paid applications. Many of those included a 30 day free trial, but I’m really looking for a long term sustainable solution. I ended up looking very close at two different packages, PSPP and R. A very common package in use is the paid program Statistical Package for the Social Sciences (SPSS). Its a very nice program from the folks at IBM, but definitely not inexpensive. GNU PSPP is a program for statistical analysis of sampled data. It is intended as a free replacement for the proprietary program SPSS, and appears very similar to it with a few exceptions. Actually there are quite a few exceptions. You can run a F-test analysis on a single factor, but I was unable to run a complete analysis on a multifactor experiment. Perhaps I was just doing it wrong, but that just didn’t work for me.

Instead I discovered the R project. Yowza, we have a winner. Its not totally intuitive as using my favorite tool Minitab, but with a bit of effort you can get some decent results…

First, download R, then run it. I’m using the R-GUI. In the console paste the following:

datafilename="C:/Users/Username/DirectoryX/dfd_coin_drop_experiment.csv" #tell where the data come from
data.ex1=read.csv(datafilename,header=TRUE, sep = ",") #read the data into a table
aov.ex1 = aov(distance_from_target~coin_size*drop_height*drop_orientation*hand_technique*target_surface,data=data.ex1) #do the analysis of variance
summary(aov.ex1) #show the summary table

The magic happens here. That last column, Pr, is the probability that the stated the null hypothesis is valid. Its is a predictive indicator. Obviously if the probability is low, than we must reject the null hypothesis as stated. For this test, we are going to look at a 95% confidence level. Large values of Pr indicate that our null hypothesis is correct, that for even though there may be differences in calculated means, because of variability in the system, the following null hypothesis is completely valid. H(0): Coin size will have no significant effect on distance to target after coin drop. Pr(>F) = 0.77268 It’s only when those probabilities are very small that differences in the factor have real effect on the response. If Pr(>F) is less than 0.05 those factors are critical to the system response. The anova routine from R includes nice visible indicators for factors that may be significant.

As you scan the Anova results, you can see that the following factors are significant.

  • drop height
  • an interaction between coin_size:drop_orientation
  • an interaction between drop_height:drop_orientation
  • an interaction between drop_orientation:hand_technique
  • an interaction between drop_orientation:hand_technique:target_surface

Do note, that in most experiments, significant dual factor interactions are pretty rare. Generally we are only concerned with single factor elements. That the factor of drop height is significant seems pretty intuitive. Coins dropped from the lower height ended up closer to the target than coins dropped from a higher height. Frankly I was surprised at the other interaction factors here. I suspect there is just a whole lot of variability in what’s going on. And I think some changes should be made to the tested factors, and the experiment re-run. I was also surprised here by some of these results. I was pretty sure we’d see coins closer to the target from the deep pile carpet than the mat, but that’s not what the results reveal. I wonder what would happen if I poured a half inch of beach sand on the carpet and rerun the test? ( Oh, I know the answer to that one, even without testing; my wife would kick me in the butt, and toss me out of the house. )

And let’s quantify the means of each test factor and combinations:

print(model.tables(aov.ex1,"means"),digits=2) #report the means and the number of subjects/cell

Finally lets plot our key factor results. Note that in the following plots, the thick black line represents the median value, the colored box represents the 25% to 75% percentile performance.

Plot — Drop Height

boxplot(distance_from_target~drop_height,main="Coin Drop Test", xlab="Drop Height (inches)", ylab="Distance from Target Center", col=rainbow(7),data=data.ex1)

[Pr(>F) = 0.00226] Its pretty easy to see here that the accuracy to target is better with a low (30″) drop height. Additionally variability is smaller with the 30 inch drop height compared to the 60 inch drop height.

Plot — Drop Height : Drop Orientation Interaction

[Pr(>F) = 0.01241]

boxplot(distance_from_target~drop_height:drop_orientation,main="Coin Drop Test", xlab="Drop Height (inches): Coin Orientation", ylab="Distance from Target Center", col=rainbow(7),data=data.ex1)

Look closely at this graph. You can see why coin orientation all by itself isn’t a significant factor. You can also see why the interaction works the way it does. Was this expected, no way. The data here is observed. But according to the test results, its a valid predictor, given those two factors defined in that way. Obviously if you want to minimize coin distance to target, you’d run your system with coin held on edge, dropped from 30 inches for best results. I will say, when I start to see interactions like these my tendency is to really analyse the system try to figure out what causes these results and adjust (or add) additional factors to further improve performance.

Plot — Drop Orientation : Hand Technique Interaction

[Pr(>F) = 0.02917]

boxplot(distance_from_target~drop_orientation:hand_technique ,main="Coin Drop Test", xlab="Drop Orientation: Hand Technique", ylab="Distance from Target Center", col=rainbow(7),data=data.ex1)

Wait, er what the heck? Look at this graph and the one above it. The results here sort of conflict with the results above. Above your solution was to hold coin on edge, but here, the optimal solution was to hold coin horizontal. Remember I said interactions aren’t all that common. Again, you may have to adjust and / or add additional factors to improve performance. There may well be a better way to solve to optimize the system’s design.

Plot — ETC…

Obviously you can continue to plot out all factors with Pr(>F) less than 0.05…

  • coin_size:drop_orientation Pr(>F) = 0.03362
  • drop_orientation:hand_technique:target_surface Pr(>F) = 0.03734


Plot — One factor that wasn’t significant…Target Surface

[Pr(>F) = 0.11383] This was kind of a surprise. I fully expected deep pile carpet to improve coin to target performance. It didn’t have a significant effect at the 95% confidence level. With the median values and variability in these results, no advantage here.

boxplot(distance_from_target~target_surface,main="Coin Drop Test", xlab="Target Surface", ylab="Distance from Target Center", col=rainbow(7),data=data.ex1)


And that concludes our exercise. I’m hoping this example makes sense. My goal was to pick a test example that intuitively gave the user a feel for what’s going on. Did the results meet your expectations? And as for open source software, it seems like R is a winner for our analysis.

Here’s a recent project for a customer that had some unique requirements. It’s for a public brand marketing kiosk type of device. But its much larger than that. In fact, the presentation has one audio output (music) and two unique video feeds. One a large tv flatscreen (with audio) and the other a simple display monitor. We wanted to give the customer a way to update the audio and video presentations.

  • Keep it simple
  • Make it reasonably secure
  • Make it reliable (Power On/Off?)

And here is the solution we came up with.

  1. We’re going to use an Intel Nuc solidstate computer to host a node.js Express server.
  2. The Node Express server API will allow for the upload and management of audio visual files.
  3. The server will play movies on dedicated url.
  4. The server will also play and manage music.We’re using https://github.com/victordibia/soundplayer, a javascript wrapper around a simple MPG123 music player program, that is available for any operating system.
  5. The interface to the server is a simple browser with a local IP address. The system includes a wifi router, but is not connected to the internet.
  6. I used the PureCSS library for the user interface

And so on…

Here’s a screen shot of the raspberry pi admin interface…

One specific issue we wanted to address was the use of Raspberry Pi devices with simple power on / off functionality. We have an approach for that. We programmed each Raspberry Pi to play a movie given as URL address, and repeat. To harden things for power off (never clever for normal Raspberry Pi use) we converted the flash drive system to read-only. Program it once, and run it forever. We’ve also provided an interface to manage the content going to each Raspberry Pi.

Here’s the recipe for the Raspberry Pi build… its pretty big, so you can download the file here… We’re using omxplayer to play the video files. Note, the info for hardening the flash drive came from https://www.raspberrypi.org/blog/adafruits-read-only/ Check the recipe file above for details…

There were a couple of pleasant surprises on this project. At one point I was getting stuck with NodeJS troubles. Not sure what happened, but I was totally unable to get the chrome browser debugger to work with my application. I ended up trying VS Code tool, something I’ve seen before but had never used. Wow. No really, wow. That tool made a whole lot of difficult tasks way easy. Many thanks, Microsoft.

The other surprise I had was related to my need for a wireless keyboard. I found this puppy from the folks at Logitech. It’s a $20 wireless keyboard / touchpad combo. I think its originally designed for sitting on the couch and surfing the web on your TV with this thing on your lap. This keyboard works seamlessly, and works quite well. I’ll use it now for every iot project. The mouse in the photo was a $10 addition, and because it too was from Logitech, one USB mini-dongle worked for both input devices.

So I was working with a customer who needed, among other things a friendly and secure telephone directory. The customer would publish a pocket sized paper pamphlet every year. Paper? Really? There must be a better way.

  • Nobody wants to download an app (from Google Play or iTunes). No way, no how.
  • Users really don’t want another login / password for yet another system.
  • Who wants to update a phone directory every time someone joins or exits the group. Not I, said your software developer.
  • We want a system that is easy to update, easy to maintain.
  • If we are talking about members telephone numbers and contact information, secure, protected access is a critical requirement.
  • Just about everyone has access to a mobile phone. Let’s take advantage of that.
  • Utilize tools in the mobile phone browser that make it easy and quick to do phone calls and text paging, via href=”tel:+1…” and href=”sms:+1…”

I had done a project using Google Apps Script and Google sheets as a data storage medium. There were some issues there.. the script ran in the browser which required an publicly shared Google sheet. Cool idea, if the use case fit that situation. Great for product listings, not great for personal data.

I saw a note somewhere about the new offerings from Google including offerings for Firebase mobile phone authentication, including a healthy free tier. Free tier, wow, I’m all in. As an introduction, Google Firebase is a suite of support tools, that was initially used in support of Android Apps. Google has expanded the offerings to include iOS, Android, and the Web. Setup includes content written for Swift, Objective-C, Java, JavaScript, C++ and Unity !
The available tools include Cloud data storage, data synch services, messaging delivery services, analytics, marketing tools and the thing I’m interested in, Authentication. The pricing for the phone authentication service free tier is pretty awesome: 10,000 / requests free per month.

The tool I’m interested in using is Authentication via phone. A website displays a mobile phone number submit. Google Firebase authenticates the phone number via a mobile sms text page with a confirmation code. As designed this is a pretty awesome way to confirm a true mobile phone number… think of marketing folks who want to harvest new users by their telephone number. (I have a couple of customers very interested in doing this type of harvesting…) And in my case, i’m taking this one step further. I’m adding specific user authentication code via “Custom Claims” by editing the Firebase user data store. The authentication code is buried in the token, provided to the web browser client via Google JavaScript bit of code. Upon receipt of the token, the website creates a AJAX request back to server. The server tests the token, and provides appropriate response depending on the users authority. Here is the reference information on using auth tokens (with custom claims) to restrict access. Note: There is a bit of a restriction placed on the free access tier from Google here. It takes a two way trip from the server to add custom claims to a users content at the Google Auth storage. The free tier limits that to 30 requests per hour. Its fine for a managing small team of users, but no way would that work for a large user base. You’d have to increase to a paid service. I will say, that’s more than fair…

Here is a sketch of the authentication process and data flow:

The whole thing works via JSON Web Tokens. JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA.

Do note, this isn’t a perfect high security system. Tokens are stored in browser cache. Anybody who shares phones is sharing the browser content. Its a lightweight security system, but probably appropriate for current usage, a phone directory or secure reference content for a small business’ employees.

Software Tools Used Here:

  • jQuery Mobile. A nice mini framework for this type of application
  • Google Firebase
  • Simple Node Express server. Framework generated via Express application generator
  • Docker used in a Virtual Private Server (proveout via docker on localhost)
  • Ajax call to server on the phone list. The server verifies token and the custom claim, then returns content
  • JSON Web Tokens
  • Google Sheets API v4
  • Mobile browser links for phone calls and text paging, via href=”tel:+1…” and href=”sms:+1…”

User Data Store:

Content is stored in a private shared Google sheet. We use Google Apps Script, and the Sheet API v4 to gain server access to the user data. Again, we’re obtaining this info from the node.js server, not from the browser. What really makes this nice is non-technical folks can easily keep the data updated via Google Drive. The data can be easily updated from a mobile phone to add new users.

Possible Enhancements:

Although I haven’t analysed all the how-to details, it should be possible to send out notifications to all users in the system via SMS messages. I can see where this could be very helpful. Another possible enhancement, more oriented to reference data, is using Progressive Web Apps to control the storage of protected data in cache. I have one customer possible application for this technology, where users are sometimes not located in an area with mobile phone reception.


The tools available from Google are pretty awesome. Firebase can be used to supplement a whole lot of applications. In this case we are using the mobile phone authentication tools to authenticate and restrict data access to a small group of users. Google Apps Script, the support tools for Google Drive applications (including Google Sheets, online spreadsheets) is way helpful for prototyping applications, or applications where non-technical folks can keep private data easily updated.

So, I’m doing some very involved woodworking, including glueing up these complicated pieces. The problem of course. is you only have so long to get things aligned and clamped up before the glue sets up. If you are not organized, or something doesn’t just fit right you are in trouble. Generally I always purchase slow set glue, so my working time is around eight to ten minutes. I will say, if things don’t go together by minute nine, then I rip the whole thing apart, let the glue dry on individual components, then come back and clean things up and try it again. With woodworking its pretty easy to fix woes (take one more cut, use a block plane or if necessary fill a gap with epoxy/sawdust mix and recut).

With that in mind, what I really want is a audible count up timer. When I’m in glue up mode, I don’t have time to be looking at the clock. Give me an audible and we’re good. At first glance I didn’t see anything off the shelf, that did this so I thought hey, I’d just write my own. And the easiest way to do that is in, you guessed it, Javascript in the browser. Without further ado, here is an audio timer!

Try it for yourself, click here.

Code pretty straight forward, the only real trick is the push/pop array for the setInterval calls. Without that, multiple button presses will drive you pretty crazy. Happy glueups!

script type="text/javascript"
     // global variable
     var x = []; // container for setInterval implementations
     var startDate;
     // functions defined here...
     function done() {
         document.getElementById("demo").insertAdjacentHTML('beforeend',"Timer Stopped...");
         console.log("All Done x: ", x);
     function startTimer() {
         // Set the date we're counting down to
         startDate = new Date().getTime();
         var msg = new SpeechSynthesisUtterance("Start Timer");
     // Update the count down every 1 second
     var tempX = setInterval(function() {
     // Get todays date and time
     var now = new Date().getTime();
     // Find the distance between now an the count down date
     var distance = now - startDate;
     // Time calculations for days, hours, minutes and seconds
     var days = Math.floor(distance / (1000 * 60 * 60 * 24));
     var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
     var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
     var seconds = Math.floor((distance % (1000 * 60)) / 1000);
     // Display the result in the element with id="demo"
     document.getElementById("demo").innerHTML = minutes + "m " + seconds + "s ";
     if (seconds % 15 == 0) {
         if (minutes == 0) {
             msg = new SpeechSynthesisUtterance(seconds + "seconds.");
         } else {
             msg = new SpeechSynthesisUtterance(minutes + " minute and " + seconds + "seconds.");
         }, 1000);
         console.log("start timer x: ", x);
end of script

Next Page »