Offline First With Flutter - Flutter Community - Medium
Offline First With Flutter - Flutter Community - Medium
You have 2 free member-only stories left this month. Sign up and get an extra one for free.
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 1/11
6/21/2020 Offline first with Flutter - Flutter Community - Medium
Welcome to the 21st century where 5G, hotspots and mobile internet is available
everywhere. It’s one of the things considered to be simply there, so you could ask
yourself:
Commute
You are in a high speed train or in the subway on an early monday morning (I know
you don’t want to be in this situation but…) and your public transport app is not
showing the next connection because you don't have a signal.
. . .
Travel
You made it — finally the time has come for your well-deserved holiday but
unfortunately you do not have a stable internet connection or it’s way too expensive.
No way to quickly check the map to get to that pizza place you checked out before.
. . .
Overload
70.000 other people are with you in a stadium watching the game of the year. And
with them at least 70.000 other phones in a relatively small spot. Goodbye, mobile
network...
. . .
Network coverage
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 2/11
6/21/2020 Offline first with Flutter - Flutter Community - Medium
Driving along the country side, hiking in a forest or simply going for walk. These are
situations that might get you into the zero network zone. I know quite a few spots
around here (in good old Germany…) that are like black holes, no mobile signal will
ever come out.
No connection? No way!
Giphy — https://gph.is/1KxOYf0
In the end it comes down to what your user expects — most of them would like to get
their content without any interruption. Processes started should offer a function to
finish them or content should allow changes — offline or online should not change
this.
L
et us divide data for your app into static and dynamic resources, everything that will
not change (or doesn’t directly influence your app’s behavior) is static — like a
picture.
Everything you process, the user types in is dynamic — like a comment for a post.
Static assets can/should be added during build time. All static assets should go to your
pubspec.yaml file, the complete process is described here. Keep in mind that a static
asset can be a picture, music or a text file (like JSON).
1 var url =
2 'https://file-examples.com/wp-content/uploads/2017/10/file_example_PNG_500kB.png';
3
4 DefaultCacheManager().getFile(url).listen((f) {
5 setState(() {
6 fileInfo = f;
7 error = null;
8 });
9 }).onError((e) {
10 setState(() {
11 fileInfo = null;
12 error = e.toString();
13 });
14 });
The above super simple example will download the image only if the local cache is
empty or expired. Sure, if the image is required, it should be a static resource but I
would like to keep it simple for the example.
M ore complex data can be handled by SQLite, actually the above mentioned
cache manager uses SQLite to keep track of the cached files. I will not explain
how to use SQLite, have a look at the related repository. Nevertheless, I would provide
one little snippet that helped me a lot, handling database upgrades for local database
can be tricky sometimes.
1 class DBProvider {
2 DBProvider._();
3 static final DBProvider db = DBProvider._();
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 5/11
6/21/2020 Offline first with Flutter - Flutter Community - Medium
Some concepts shown here are for Flutter but the general idea works also for websites,
have a look at Google Docs, a perfect example of an offline capable website. Google
Maps also has a nice offline function, allowing you to download an area and use it
offline.
Giphy — https://gph.is/1Ko0IQ6
One short section before we look at code — let’s break our effort down into three
implementation steps:
1. Offline mode
Local cache / DB and general data storage
2. Online mode
Synchronization
3. On/Off UI pattern
The above code is a DB provider I use for some Flutter apps. Let’s quickly cover the
database upgrade part:
1. Requesting the database will create it one time due to the static property that is
shared between all instances (see the get database property)
4. Creation and upgrade makes use of batch execution, all statements are run in one
request
6. During update all elements of the map will be added to the batch (in the right
order) and executed
The map mentioned in step 5 can be seen as a book — the first element is the page
number (as int) and the second element the content of the page. If you would start
reading a book somewhere in the middle you most likely have no clue what’s going on.
If you continue to read page by page from where you left (in our case the
currentVersion) the story will make sense.
Our database get’s updates from the currentVersion up to the latest available, all
executed in the right order in a single batch operation.
Since I wrote this article I checked out a lot of other local storage solutions. Have a look
at the linked article, moor is a nice package to assist you with offline first storage.
Giphy — https://gph.is/2HPEMQz
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 8/11
6/21/2020 Offline first with Flutter - Flutter Community - Medium
There are a billion options on how you can do this, as pointed out earlier this depends
on your needs. I can just hand over some advises learned over the years, all our mobile
apps have to be offline first, all of them have a sync build in.
If you can, use an already build sync service — do net reinvent the wheel
Please do not use integers for primary keys, instead use UUID offered by this super
simple package, otherwise you might find yourself in the unlucky case of creating
integers in given ranges for given clients. UUID’s are always unique¹
Keep the exchanged data as small as possible, implement a change flag or last
change date. Setup a data contract for all your data — this contract should describe
the minimum required for all data (ID, last change), only send out data newer as
the last sync
Store timestamps in UTC to don’t end up in the timezone hell. Consider saving
them as plain numeric values, this works for any kind of backend
Keep the mobile side of the API as dumb as possible, if you have a bug in the app, a
fix might take 2 days before it reaches your customer. Fixing a server side bug
should be much faster
Think about your API architecture twice, over/under fetching data is an issue of
REST, a possible solution would be GraphQL
¹ The probability to find a duplicate within 103 trillion version-4 UUIDs is one in a billion.
From Wikipedia
M ake sure your content offers interaction, even if you end up with “Sorry, no
network, try later”, you still get further as hiding parts of your app.
Ensure that the workflows are the same, offline or online, there should be no
difference.
In case you can’t handle a request, please provide a meaningful error message.
Messages like the ones below are useless:
An error occurred
Internal error
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 9/11
6/21/2020 Offline first with Flutter - Flutter Community - Medium
No response
Try something like: “Sorry, you seem to be offline. The current request can’t be
completed.” If you have a certain function that will require a connection in any case,
check the current connection state and disable the button if you are offline.
Pro mode — leave the button active but inform the user after he clicked that this can’t
be done right now.
Think about your empty states, showing a big white rectangle because a list view is
empty doesn’t help you. Include a nice image and a short text that get’s the user
started/informed. Asking a user to confirm an action that will require a network
connection can also be a helpful tool in case you need to perform a longer running
operation.
How about you? Did you ever made an offline-first app? I would love to see some
examples or any experience in the comments :)
Flutter Community
The latest Tweets from Flutter Community (@FlutterComm). Follow to get
noti cations of new articles and packages from…
www.twitter.com
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 10/11
6/21/2020 Offline first with Flutter - Flutter Community - Medium
https://medium.com/flutter-community/offline-first-with-flutter-be1e8335d976 11/11