Flutter
GraphQL

Offline Database

11min

Implementing the offline first database using the GraphQL API

Introduction

Since you are here, you must have gone through the rest of the tutorials and are familiar with executing GraphQL queries and mutations to fetch and mutate the data. In this docs, we are going to explore how to implement an offline first user interface with Flutter and GraphQL.

Goals

  • Understand internal architecture of the flutter graphql offline client
  • Allowing application to run graphql queries even though application is offline
  • Implement Offline data persistence

Prerequisites

  • We require that the user has some basic understanding of Dart and Flutter.
  • Though not necessary, the GraphQL cookbook will be useful in understanding some of the GraphQL concepts.
  • We require that you have completed the prerequisite topic Flutter Graphql Setup and have previous code setup and back4app backend implemented.

1 - Setting up offline cache

Flutter GraphQl client supports “offline queries” by default, that is it will not throw errors if we query some GraphQL data when offline and would fetch the data from cache.

We have to note that this is different from persisting the cache across app sessions and specifically the flutter graphql client does not have cache persistence to disk. So if the app closed from the system tray and reopened the data would still need to be fetched.

To enable the same we have to enable the offline cache:

Go to main.dart:

Dart


2: Setting up stored preferences

One caveat while using the flutter-graphql client is that it does not store any cache of its own when the application is closed, nor does it hydrate the cache when the application is opened again.

For implementing the same we would be leveraging the flutter shared_prefrencces library. It wraps platform-specific persistent storage for simple data (NSUserDefaults on iOS and macOS, SharedPreferences on Android, etc.), essentially allowing to store data offline in a very simple manner.

For installing the library please add in the pubspec.yml file

shared_preferences: ^0.5.12+4

In main.dart add the following:

Dart


Shared Preferences library stores data in a key-value form where value gets stringified into a JSON string. We will need to parse this data to our data model.

3 - Parsing the locally stored data

We will create a new file called programing_languages_model.dart. Which will store the parsing logic. We will generate this logic by pasting our graphql response in the JSON to dart model converter at https://app.quicktype.io/

Document image


We will copy the generated code and create a file programing_languages_model.dart https://github.com/templates-back4app/Flutter-GraphQL/blob/flutter-graphql-offline/lib/programing_languages_model.dart

4 - Integrating Offline Storage logic

If the data does not exist we would be using the data from shared preferences. If the data is also not in the shared preferences we would simply show a loading icon.

We will now implement changes to integrate all the changes together, in the build method of our _MyHomePageState we would change our build method. We would use the FutureBuilder widget to consume data from the SharedPreferencesHelper class.

Dart


Using the FutureBuilder widget allows us to write code without having to use state. It is a relatively quick process to get the data from shared preferences. We could also show a loader while we are initialising the shared preferences and are getting data from an offline store.

We now use this offline data object and render while data from GraphQL is not available. We will also refactor the code a little bit. Following will be our code for the Queryhttps://github.com/templates-back4app/Flutter-GraphQL/blob/flutter-graphql-offline/lib/main.dart widget.

Dart


We should get the following:

Document image


Conclusion

We are now able to ensure a very good mobile experience by storing the data offline and revalidating the data when the application gets connected to the internet. Also, one important aspect that is enhancing the user experience is that the flutter-graphql client caches the old response and while sending a new request automatically. Because of which we don’t have to keep showing clumsy loading screens, while re-fetching data.