I would like to write in this post about problems I have had recently with my dictaphone FirefoxOS app, hoping it will help other developers avoiding the pitfalls I have fallen into. My advice falls into two categories
Think twice before you choose a FirefoxOS app type
When one wants to develop a FirefoxOS app, one first has to choose a type of application: either hosted or packaged, then submit the app to the FirefoxOS marketplace for review. A hosted app (as the name implies) is hosted on the developer own web server and can be consumed by any number of browser (FirefoxOS, Firefox desktop, Chrome, iOS…), because it is basically a classic SPA with an extra manifest file. A packaged app is hosted by the marketplace itself, and distributed as one zip file. It is specific to FirefoxOS. Packaged apps can request extra privileges (such as access to the device SD card using the Device Storage API): code reviewers at the marketplace make sure apps do not abuse these privileges.
The difference between the two types of app is well explained in MSDN, however the fact that this initial choice is crucial and has far-reaching consequences is not sufficiently emphasized. Indeed, there is no upgrade path from a hosted app to a packaged app. One cannot say: “I will start with a lightweight hosted app, add more features, and if it turns out I need more control of the device for these features, I will migrate the app to a packaged app”. This scenario is not supported. The only way out is to create a second, different app (even though the code is completely identical, except the manifest) and re-submit it as a packaged app.
Alas, this has far-reaching consequences. Developers basically loose their user base and need to start afresh, under a new app name. They need to convince users to install the new packaged app and use it instead of the original hosted one. Users of the original hosted app are stranded with data stored in that app IndexedDB. That data cannot be imported into the new packaged app.
Why is that ? It boils down to the model used by FirefoxOS to identify an app. Hosted apps are identified by the URI at which they can be downloaded, whereas packaged apps are identified by a automatically, install-time generated GUID. The OS has no notion of relationships between apps. Since it cannot for obvious security reasons let one app tap into the data generated by another one, data migration between a hosted and a packaged app is not possible (unless one uses an external server to manage export/import, which would cause all kinds of new problems).
I did not make the right choice with the dictaphone app. I started as a hosted app. A that time, I saw no need for privileged APIs because all I needed was to grab the microphone (WebAudio/MediaCapture) to capture sound and use IndexedDB to record them. Other more advanced APIs (such as the Recorder API, which appeared in FFOS2.x) had not been developed at the time. Furthermore, I saw no reason to limit the app to FirefoxOS if it could work on other browsers too, an approach which seemed encouraged at the time by MDN through articles documenting “Open Web Apps”. The app was very successful at first, because it added a feature which is useful to a lot of people. However very quickly users began rightfully to ask for a feature to export their recordings out of IndexedDB to the device SD card. Alas to access the SD card, one needs to use the Device Storage API, which is a privileged app available only to packaged apps. Ooops ! There is no way I can provide this functionality. I need to create a new app for that.
Be aware of fragmentation and stick to basic APIs
Fragmentation does not only happen in Android. It also happens to FirefoxOS devices and a lot of the early adopters are stuck with early versions of the operating system (1.0x), either because the manufacturer has not ported FirefoxOS upgrades to their device, or because the phone operator does not provide support for upgrades. The marketplace does not currently filter the apps based on the capabilities of the device or its operating system version. Therefore, developers had better have an application which can degrade gracefully for early versions of the operating system. If it turns out the core functionality of the application cannot be implemented in old FirefoxOS devices at all (as is the case with dictaphone), developers should consider whether or not to develop the app at all.
Indeed, the bulk of the users for these apps are non-technical people. They expect the thing to just work and if it does not they will blame the developer. This translates into a bad experience of angry feedback, insults and 1 star grades.
Conclusion
Paul Rouget from Mozilla very gently contacted me to inform me about the new Recorder API (available in FFOS2.x), suggesting I should changed the app to use it instead of my homemade WebAudio/MediaCapture codec. He is right of course (technically). However at the moment I have not found the will to do that, because I will face the following issues. Users of 1.x who are currently satisfied by the app will be pissed off because they will not be able to re-import their data in 2.x. Users of 1.x who cannot currently use the app because it requires at least 1.2 will be even more unhappy if I suggest they try 2.x instead. Users of 1.x who cannot upgrade their OS to 2.x will also be unhappy.