(revised Feb 7, 2014)
We’ve been syncing FileMaker Go solutions since June of 2011 and it now seems like a good time to reflect on what we’ve learned helping folks make mobile apps as well getting the apps they already have debugged, sped up, and syncing.
This article will talk about some of the things we think are most important–and maybe counter intuitive–when planning a distributed app.
Because that’s the big shift for most of us: we’ve been making networked apps, and now that we’re mobile we’re making distributed systems. This is often much more of a shift in perspective tham the constraints of the mobile interface itself.
Distributed FileMaker Files
Offline is THE Mobile Use Case.
With all this power and flexibility to make sophisticated back-office apps, we sometimes forget that the simplest mobile apps often deliver huge benefits. Some of the biggest impacts we’ve seen our customers’ make in their business have been with simple, single-table solutions that look pretty simple compared to the stuff we’re used to making.
But it’s the access to these simple apps that makes them powerful–they’re out with agents, nurses, and inspectors when and where they need them–and this means these apps are almost always working offline.
Partly this is just a function of FileMaker Server: it’s so much faster to open and work with a local app, that even when folks in the field have internet access, they want their FileMaker Go apps faster than connecting to the server allows.
Watching a customer demo one such simple app from the stage of their shareholders’ meeting last night, in this bunker of a convention center, without ever worrying if they could get online really brought this home to me: fast, dependable apps are apps that work offline.
The Mobile File is not the Hosted File.
In the best systems we’ve seen– and in all systems that have been up and running more than a few months–the mobile file diverges from the hosted file. In the best systems it diverges greatly, and not just because it has it’s own interface constraints.
To begin with, there are all sorts of functions that aren’t performed on the mobile file: reports that aren’t run, accounting that isn’t needed, etc. More importantly, the mobile users have different roles and goals than the folks using the mothership system. As their requirements are really understood, the mobile file simplifies over time. New functions don’t glom into the mobile file like they do the in the mothership solution: mobile apps become their own simple, single-mission files.
This is one reason it’s important to use a sync framework that can distribute new versions (new .fmp12 files) of your mobile app.
The Mobile File has a Subset–often a Small Subset–of the hosted data.
Just as the interface of a mobile app is more focussed (you’ll see almost no navigation in the best apps), the scope of the data is more focussed as well. Mobile users want to get to work quickly and often need mission-specific, focussed applications with just their data.
So we see inspectors pulling down just the uninspected properties assigned to them that week, repair technicians syncing just the workorders for their customers, and mobile health care aids seeing just their patients that need to be visited that day.
In addition to helping the mobile user focus, these narrowly scoped found sets mean faster syncs (especially over cellular connections), and no collisions between users trying to edit the same records.
Tactics for Syncing FileMaker Apps
Ok, so if that is what successful apps look like, what should I actually do to make a successful FileMaker Go app?
Well, here is what’s worked for us and our clients.
Sync is hard, use a framework.
We’ve seen lots of folks roll their own sync, but very few end up with something solid. Sync is hard: just look at Mobile Me. =)
And to make things worse, a lot of what seems like it should work in FileMaker, just doesn’t help when it comes to sync. For example, importing records won’t cut it. Under the hood, commits are streamed to the server during import, so if something happens during the sync, you and your app won’t know which records have synced and which haven’t. Maybe not a problem, you can always sync again… except when you don’t bother because you think everything made it, or when you have server-side processes grabbing those (perhaps partially) uploaded records and doing something with them.
It’s worth talking about imports in a bit more detail–and here we’re talking about the import idea itself, regardless of how the data got to the server (you may have emailed it, sent a file, sent a URL request, etc.). Imagine a mobile sales rep who has 10 sales invoices to send back to the server. Each invoice is made up of an invoice record and one or more invoice line items. So if you’re importing records into the server from your mobile file and the connection drops, you may get all your invoice records, but none of your line items. Worse, you may get *some* of your line items so at least one invoice will appear complete, but will only have some of it’s line items. Does your app consider that invoice “uploaded” or not? Without sending the invoice as a transaction, you can’t really know. And that’s the problem with importing: it’s just not transactional.
(You may not think you need transaction–after all, with other methods the data will “eventually” get to the server, but when you need to distribute a new version of your mobile app, you need to know that the data in your local copy has made it to the sever before you clobber that file.)
Neither is email, of course. Email is cool for small stuff but it’s again hard to know that the emails made it. And it can be very hard to pull records INTO FileMaker Go using email.
Dropbox is particularly promising and while it can work if you’re (very) careful, the kind of sync Dropbox does is what’s called “eventually consistent”. The idea is that you may not have the latest copy of the file right now, but you will if you just wait a bit. And while that can sometimes be fine, if you need to make business decisions based on this data–or, for example, visit sick patients–you need to KNOW if you have the latest data: you need to know that your sync completed, instead of merely started.
Currently there are three sync frameworks you can use so you don’t have to roll your own…
GoZync, created by myself and Todd Geist, and
MirrorSync, by 360Works.
SyncDeK2Go by Linear Blue.
To wrap up, unless you want to spend a lot of time and effort handling all the intricacies of sync, proudly benefit from the experience of others, and use a framework.
Syncing “in the background”: sounds great, but your users will hate it.
To begin with, this can’t really be done as we don’t have a great way to measure signal strength in FM Go, and anything we can do to test for a wireless connection pulls the user’s focus off what they’re doing, like typing. But even if we did have a reliable way to test signal strength, the user needs to decide when to sync.
Here’s why: just because the device has signal, it doesn’t mean the user is going to stay in that location long enough to sync. Worse, they may need their app before the “background” sync completes: imagine you’re in the parking lot of your prospect’s office and you look down at your iPad to review their quote only to see that it’s syncing another customer’s (voluminous) product photographs down from the server.
Remember: keep your syncs fast, scoped to the user, and on-demand. (You might also enjoy this, about the urgency of mobile work.)
Sync Feedback: mark local records as “uploaded”
We’ve found that users really like it when apps let them know a given record has been uploaded to the server. Showing a little icon or message–that the user can trust–lets a salesperson confidently close their iPad for a week’s vacation knowing that their important sale actually made it up to the office.
UUIDs are like the serial numbers most of us use to uniquely identify our FileMaker records, but UUIDs have the advantage of being unique across multiple devices. We have a nice article on why to use these and how to convert to them here, but for now, just know that in a distributed system you *must* have UUIDs to keep your data straight.
Even “eventually consistent” sync frameworks that appear not to use UUIDs (like Dropbox and MirrorSync) actually use them under the hood. So use UUIDs as the primary keys (relationship matches) in your FileMaker tables: you’ll be glad you did.
Syncing Photos and Videos
We don’t have any customers syncing videos right now. That is a LOT of data to send over a shaky internet connection. But photos are a big part of most of our customers’ mobile solutions. A couple of tips:
- FileMaker 12′s managed storage works great on hosted files, but your mobile file should use local storage.
- Consider syncing your photos on their own terms if you can instead of every time a field in the record changes. Photos take longer to sync so if you can sync isolate them as related records or as their own sync operation, your users will sync more often.
- Think about using a separate sync button for photos that folks may use only when they’re on solid wifi, or at the end of the day.
- Use FileMaker 12′s GetThumbnail feature to manage the size of photos taken on the iPad before you try to sync them. But do this thumbnailing with scripts instead of auto-enter calcs or you’ll have those thumbnail calcs running when you sync photos down to the iPad slowing things down.