Behind the Curtain: A Re-Introduction

It’s been a year since I’ve lasted posted here, and quite a lot has changed.

As we continue to grow, we’ve been reviewing our external communication channels, and started exploring new ways to engage with our customers. There aren’t many direct means of contacting our developers, but we do read the forums weekly.

One thing we introduced late last year are developer Q&A sessions. We have had 2 so far in November and February, and our next one is coming up in May. We are planning for the Q&A sessions will coincide with our app updates, which we are aiming to release at the beginning of each quarter.

Aside from the Q&A, we’re going to begin posting regularly on this blog each week, rotating between developers. We’ve added a few new faces to the development team, who you will all meet soon through this blog as well. I will let them introduce themselves in the coming weeks.

Of course this really wouldn’t be a look behind the curtain if I didn’t give you guys a sneak peak of what is coming up. The main focus for the past couple of weeks has been a new feature which will allow creation of “Assignments”.

These could be anything from ordinary station assignments to specific crew assignments or even roster status assignments. The main idea is to give your agency the ability to know who is supposed to be assigned to what at any given time. A simple example would be setting up assignments to represent your multiple fire houses, and scheduling which house everyone should be at each shift.

We’re really excited to roll out this feature in the upcoming month, and will putting out a testable sandbox later this week. Look for a link to it in the upcoming newsletter!

Behind the Curtain: Inter-App Communication

I’ve been working on another Android app the past couple weeks. We’ve added a couple of features, included enhanced logging and a couple of night-mode themes.

One thing that has been often requested is a way to launch Scanner Radio from our app.
I got in contact with the developer of Scanner Radio and he gave me a snippet of code that allows Active911 to launch the Scanner Radio selector.
The main problem I’ve been working on overcoming today is how to store the Intent that is given back in the ActivityResult of the selector.

There’s not really a good way to serialize an Intent in Android, it seems that they are intended to be passed and immediately used.
The design pattern for most Inter-Process Communication is defining an Intent schema that can be used by external applications.
Another pattern used is exposing an external Service, which I haven’t looked into much.

Regardless, right now I have an Intent that, when used immediately, works as intended. However, I can only use that intent as long as the app is open, so I need to find a way to persist the Intent while maintaining all of its required information.

At first I tried just using the Intent.toUri() method. That gets me halfway there, as the URI still doesn’t contain any of the Extras in the Intent.
The next thing I tried was manually serializing the data into tab-delimited name value pairs. However, this doesn’t work as I don’t necessarily know if the extras are all Strings, as well as how many layers of nesting there are.

My final strategy is to take the Bundle and serialize it into a byte array, and then store that byte array as a UTF-8 string, then reversing the process to get it back out.
This stackoverflow answer was the most helpful in figuring out how to do so

The downside to this is that, since the class implementing Parcelable may change between platform versions, this is not guaranteed to work across system updates.
Also, after digging through the Parcel and Bundle source code, it seems that the Intent may be too large to serialize and deserialize in this way.

It looks as though the extras only has a single item, so instead I will be just serializing and deserializing this one item.
It contains a set of 3 name value pairs, so I will serialize that into JSON, though serializing it into byte data did work initially.

In the end, I ditched the Parceling and byte storing of the data, since that is highly discouraged, and just stored the name value pairs.
As long as the bundle doesn’t get deeper, have a change in the name of the extra, or use anything other than Strings in the sub-bundle it will work.

The Android update with a Scanner Radio setting is hitting our new Beta group today, and will likely be updated in the Google Play store next week.

Behind the Curtain: Goodbye TestFlight

With Apple’s acquisition of TestFlight’s parent company, we received notice that TestFlight will no longer serve up Android builds as of March 21st.

While unfortunate, we must persevere. I’ve begun looking at options for replacing TestFlight.

The first option I considered was switching over to just using Google Play for both Beta and Release versions.
This would allow all of our Android deployments to come from one place, though it would mean that users would have to choose between Beta and Release for all their devices, whereas they can have different devices using different versions currently.
Also, Google’s analytics are geared more towards user engagement and marketing rather than Beta testing.

The second option we are currently considering is a site called TestFairy. They immediately jumped on TestFlight’s recent announcement about discontinuing Android support by welcoming former TestFlight users, even providing hooks that allow apps which include the TestFlight SDK to not need any code change at all. A very smart move.
So far, in my 1 day of testing, I am fairly impressed with the polish and extensive metrics provided by TestFairy. Not only does it gather checkpoints that I’ve set, it is able to monitor memory, CPU, Network, Phone Signal Strength, Battery, and even allows for screencast recordings.

The one snafu that I encountered was Google Maps initially not working with our app. Sadly, the documentation is a bit lacking, though the interface is very clean and simple so it doesn’t matter so much for the most part.
In the end, I was able to figure out that, since TestFairy actually modifies our SDK to add in the metrics gathering, it has to sign itself with TestFairy’s signing key. There is a field under App > Settings > Signature that shows Facebook and Google API keys, which, upon mousing over, reminded me that I needed to add the TestFairy signed package to our Google Maps API allowed apps.

Overall, I am thoroughly impressed with TestFairy’s capabilities, if still a little weary of the fluffy name. Hopefully, unlike TestFlight, they won’t poof and disappear on us. I’ll be testing TestFairy for a couple more days, but expect us to switch over to using it for Beta next week.

Behind the Curtain: Developer API Alpha

I am putting the finishing touches on the API Alpha Release this week, as well as an example web application.

The preliminary documentation for getting started is on our new Wiki at http://wiki.active911.com/wiki/index.php/Active911_Developer_API
The JSON is still fluid so I may be changing a few of the device/agency/alert/response attribute names.

I did have a bit of trouble yesterday in making a test application. While getting the cross-site scripting to work, I stumbled on 2 errors.
First, I spent almost an hour debugging invalid requests, trying different Apache configs and different data formats, before realizing I had inadvertently typed access.or.active911.com instead of access.active911.com (facepalm)

After I figured that out, I had to learn a bit about CORS and HTTP Headers. It seems that, if you want to set headers like Authorization, you first need to establish which headers your page will accept from another domain. I kept running into 401 errors and, upon inspecting the request, found that my Authorization header was not being sent. (Using jQuery’s AJAX method and a beforeSend to insert the OAuth2 Bearer Token)

After some more fiddling with the AJAX and digging around the internet, I found that I needed to accept the OPTIONS request method, which I had previously not heard of.
Once I figured that out, it was a simple matter to implement the preflight workflow and enable CORS for my web application.

Please try out the API and let me know how it works for you. We will be continuously improving it as time goes on.

Behind the Curtain: User Access

We are looking at ways to give every agency more ways to personalize and add content for their users.

One upcoming change we are considering is giving all users the ability to create their own account, regardless of the settings of any particular agency.

Currently, the only way to create a user account it to be an administrator of an agency or have one created by the an administrator.

However, we’ve come across some cases where the administrator does not want to create accounts for users because they are afraid their users may inadvertently mess up some settings for the agency.

Unfortunately for those users, being denied a login account also prevents them from participating in our forums and user polls.

As such, we will most likely be removing the agency setting that enables/disables account creation. However, this does not necessarily mean that everyone will be able to see their devices. Administrators will still be the ones that create devices, and to create an account users will still need to provide an email that is associated with a device.
This means that if an administrator sets the email address of all devices to just the administrator’s email, people will still be unable to create an account, but there does not seem to be a good way to get around it besides suggesting that administrators abandon that practice.

If you have any thoughts on other ways to improve the user experience on our website, please comment below!

Behind the Curtain: Catching Up

I’ve fallen a bit behind on my blogging since the new year.
I have 2 posts which are half finished, both regarding new features that are coming up this year.
I hope to complete those and out to you all this week and next.
As with any growing company, we’re reaching a critical point of juggling multiple pressing features.

Currently, I have an Android update waiting in the wings that I hope to put out to the Testflight group today and release to the public next Monday.
I have the OpenAPI which requires both an OAuth implementation as well as a RESTful architecture to implement, which I hope to have an initial implementation of by early February.
I have a change I need to make that will default to our new SMS shortcode for all agencies in the US and an international number for all others.
And then I have the daily little “fires” to put out each day.

There’s certainly enough to keep even twice our number busy.
So if I do forget to reply to an email or request in a timely fashion, please don’t hesitate to send me reminders.
I may have that information/change sitting on my desk/desktop, just waiting for me to remember it’s there.

Behind the Curtain: Database Whoa’s

Aside from the newly released Custom Response Buttons, we did a bit of work behind the scenes relocating our main database server to a beefier piece of hardware in our Texas datacenter.
This resulted in around 0.1s of increased lag when loading up a page through our website or mobile interfaces, barely noticeable in most cases.

Our support team however started noticing huge slowdowns in their ability to browse through our websites, along with a couple of administrators for large counties with multiple agencies.
It turns out one of our authentication methods is using multiple queries for each agency a user is a part of, which doesn’t pose much of a problem when turnaround to the database is 10ms, but quickly adds up when queries start taking 100ms or so.

I’ll be working on optimizing this, either by removing the extra queries and putting them into the workflow somewhere else, or by combining them into an already existing query.

The advantage of putting the queries elsewhere in the workflow are that they will no longer affect every page request, and will only be called when needed.
The disadvantage of course is the proliferation of operations in our interface, which is rapidly growing as we add more nuances and functionality. We have talked about a web interface revamp in the near future, so this may be the correct solution until we can get to that project.

The advantage of putting the queries into one big one is that it will keep the logic in the same place, thus keeping our workflows streamlined and simple.
The disadvantage is that the query may become so big an cumbersome that it is too complex to work efficiently, as well as maintain in the future.

Either way, we are due for a reworking of the website in the near future as neither is a great solution, and will require some restructuring in order to remain scale-able for the future.

Behind the Curtain: Holiday Hacking

I had finished the iOS and Android pieces of our custom response buttons before driving off to our annual holiday stay at my in-laws, but had completely forgotten Webview and SMS.

The custom response buttons was on top of your wishlists, and we wanted to be sure nobody felt like the only kid without a Red Ryder BB Gun.

The advantage of working with 1′s and 0′s is that you can do it pretty much anywhere. After sneaking in some hacking between bites of holiday ham and unwrapping presents, I was able to push out the final pieces for response buttons today to all our agencies.

Happy Holidays everyone, don’t shoot your eye out!

Behind The Curtain: The Bleeding Edge

We’ve often discussed the increasingly slow pace of deployments here at the office (not to be confused with The Office, our mistakes entail a lot less laughing and a lot more crying).
Unfortunately, as we grow larger, more complex, and with more agencies relying on our service, it becomes riskier to deploy quick late-night hacks at a moment’s notice.
We usually go through at least 2 weeks of testing, and even then we can’t anticipate all the corner cases that are out in the field.

We’ve toyed with the idea of bringing up a secondary system that would be deployed to much more frequently, but with things breaking frequently as well.
The benefit for agencies would be more frequent updates, and for us would be finding bugs faster.
The downside of course is that it could, and would, break at any moment, though the fixes would also be deployed faster as well.

Would anyone be interested in signing up for this sort of bleeding edge system for their agency, or would the instability make it pretty much unusable to anyone?

Behind the Curtain: OpenAPI and OAuth2.0

As we progress in developing our OpenAPI, we’ve come across many use cases that are similar to what lots of people have already done, ie giving access to protected resources to a 3rd party app.
As such, we’ve decided to scrap our homegrown authentication scheme and go with doing OAuth2.0 style authentication instead.
This will allow users to enable and revoke access to the application on a per-user basis rather than the application as a whole.
If anyone has any experience with OAuth2.0 or any other authentication architecture, such as OpenID, and would like to share their experience, we are not set in stone on this and still have a ways to go in terms of development. Please feel free to comment below on your experience.