Set up Amplify DataStore
DataStore with Amplify
Amplify DataStore provides a programming model for leveraging shared and distributed data without writing additional code for offline and online scenarios, which makes working with distributed, cross-user data just as simple as working with local-only data.
Goal
To setup and configure your application with Amplify DataStore and use it to persist data locally on a device.
Prerequisites
- An Android application targeting Android API level 16 (Android 4.1) or above
- For a full example of creating Android project, please follow the project setup walkthrough
Install Amplify Libraries
Add the following dependencies to your build.gradle (Module :app) file and click "Sync Now" when asked:
dependencies { implementation 'com.amplifyframework:aws-datastore:ANDROID_V1_VERSION'
// Support for Java 8 features coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'}
At the top of the same file, add compileOptions
to support the Java 8 features used by Amplify:
android { compileOptions { // Support for Java 8 features coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }}
Setup local development environment
To use Amplify, you must first initialize it for use in your project. If you haven't already done so, run this command:
amplify init
The base structure for a DataStore app is created by adding a new GraphQL API to your app.
# For new APIsamplify add api
# For existing APIsamplify update api
The CLI will prompt you to configure your API. Select GraphQL as the API type and reply to the questions as shown below. Conflict detection is required when using DataStore to sync data with the cloud.
? Please select from one of the below mentioned services: `GraphQL`? Here is the GraphQL API that we will create. Select a setting to edit or continue: `Name`? Provide API name: `BlogAppApi`? Here is the GraphQL API that we will create. Select a setting to edit or continue: `Authorization modes: API key (default, expiration time: 7 days from now)`? Choose the default authorization type for the API `API key`? Enter a description for the API key: `BlogAPIKey`? After how many days from now the API key should expire (1-365): `365`? Configure additional auth types? `No`? Here is the GraphQL API that we will create. Select a setting to edit or continue: `Conflict detection (required for DataStore): Disabled`? Enable conflict detection? `Yes`? Select the default resolution strategy `Auto Merge`? Here is the GraphQL API that we will create. Select a setting to edit or continue: `Continue`? Choose a schema template `Single object with fields (e.g., “Todo” with ID, name, description)`
Idiomatic persistence
DataStore relies on platform standard data structures to represent the data schema in an idiomatic way. The persistence language is composed by data types that satisfies the Model
interface and operations defined by common verbs such as save
, query
and delete
.
Data schema
The first step to create an app backed by a persistent datastore is to define a schema. DataStore uses GraphQL schema files as the definition of the application data model. The schema contains data types and relationships that represent the app's functionality.
Sample schema
For the next steps, let's start with a schema for a small blog application. Currently, it has only a single model. New types and constructs will be added to this base schema as more concepts are presented.
Open the schema.graphql
file located by default at amplify/backend/{api_name}/
and define a model Post
as follows.
type Post @model { id: ID! title: String! status: PostStatus! rating: Int content: String}
enum PostStatus { ACTIVE INACTIVE}
Now you will to convert the platform-agnostic schema.graphql
into platform-specific data structures. DataStore relies on code generation to guarantee schemas are correctly converted to platform code.
Like the initial setup, models can be generated either using the IDE integration or Amplify CLI directly.
Code generation: Platform integration
Code generation via the amplify-tools-gradle-plugin
Gradle plugin is deprecated, so please use the Amplify CLI instead.
Code generation: Amplify CLI
Models can also be generated using the Amplify CLI directly.
In your terminal, make sure you are in your project/root folder and execute the codegen command:
amplify codegen models
You can find the generated files at app/src/main/java/com/amplifyframework/datastore/generated/model
.
Initialize Amplify DataStore
To initialize the Amplify DataStore, use the Amplify.addPlugin()
method to add the AWS DataStore Plugin. Next, finish configuring Amplify by calling Amplify.configure()
.
Add the following code to your onCreate()
method in your application class:
Amplify.addPlugin(new AWSDataStorePlugin());
Your class will look like this:
public class MyAmplifyApp extends Application { @Override public void onCreate() { super.onCreate();
try { Amplify.addPlugin(new AWSDataStorePlugin()); Amplify.configure(getApplicationContext());
Log.i("MyAmplifyApp", "Initialized Amplify"); } catch (AmplifyException error) { Log.e("MyAmplifyApp", "Could not initialize Amplify", error); } }}
Amplify.addPlugin(AWSDataStorePlugin())
Your class will look like this:
class MyAmplifyApp : Application() { override fun onCreate() { super.onCreate()
try { Amplify.addPlugin(AWSDataStorePlugin()) Amplify.configure(applicationContext)
Log.i("MyAmplifyApp", "Initialized Amplify") } catch (error: AmplifyException) { Log.e("MyAmplifyApp", "Could not initialize Amplify", error) } }}
RxAmplify.addPlugin(new AWSDataStorePlugin());
Your class will look like this:
public class MyAmplifyApp extends Application { @Override public void onCreate() { super.onCreate();
try { RxAmplify.addPlugin(new AWSDataStorePlugin()); RxAmplify.configure(getApplicationContext());
Log.i("MyAmplifyApp", "Initialized Amplify"); } catch (AmplifyException error) { Log.e("MyAmplifyApp", "Could not initialize Amplify", error); } }}
Upon building and running this application you should see the following in your console window:
Initialized Amplify
Persistence operations
Now the application is ready to execute persistence operations. The data will be persisted to a local database, enabling offline-first use cases by default.
Even though a GraphQL API is already added to your project, the cloud synchronization will only be enabled when the API plugin is initialized and the backend provisioned. See the Next steps for more info.
Writing to the database
To write to the database, create an instance of the Post
model and save it.
Post post = Post.builder() .title("Create an Amplify DataStore app") .status(PostStatus.ACTIVE) .build();
Amplify.DataStore.save(post, result -> Log.i("MyAmplifyApp", "Created a new post successfully"), error -> Log.e("MyAmplifyApp", "Error creating post", error));
val post = Post.builder() .title("Create an Amplify DataStore app") .status(PostStatus.ACTIVE) .build()
Amplify.DataStore.save(post, { Log.i("MyAmplifyApp", "Created a new post successfully") }, { Log.e("MyAmplifyApp", "Error creating post", it) })
val post = Post.builder() .title("Create an Amplify DataStore app") .status(PostStatus.ACTIVE) .build()
try { Amplify.DataStore.save(post) Log.i("MyAmplifyApp", "Saved a new post successfully") } catch (error: DataStoreException) { Log.e("MyAmplifyApp", "Error saving post", error) }
Post post = Post.builder() .title("Create an Amplify DataStore app") .status(PostStatus.ACTIVE) .build();
RxAmplify.DataStore.save(post).subscribe( () -> Log.i("MyAmplifyApp", "Created a new post successfully"), error -> Log.e("MyAmplifyApp", "Error creating post", error));
Reading from the database
To read from the database, the simplest approach is to query for all records of a given model type.
Amplify.DataStore.query(Post.class, queryMatches -> { if (queryMatches.hasNext()) { Log.i("MyAmplifyApp", "Successful query, found posts."); } else { Log.i("MyAmplifyApp", "Successful query, but no posts."); } }, error -> Log.e("MyAmplifyApp", "Error retrieving posts", error));
Amplify.DataStore.query(Post::class.java, { matches -> if (matches.hasNext()) { Log.i("MyAmplifyApp", "Successful query, found posts.") } else { Log.i("MyAmplifyApp", "Successful query, but no posts.") } }, { Log.e("MyAmplifyApp", "Error retrieving posts", it) })
Amplify.DataStore.query(Post::class) .catch { Log.e("MyAmplifyApp", "Error retrieving posts", it) } .collect { Log.i("MyAmplifyApp", "Post retrieved successfully") }
RxAmplify.DataStore.query(Post.class).subscribe( post -> Log.i("MyAmplifyApp", "Successful query, found post."), error -> Log.e("MyAmplifyApp", "Error retrieving posts", error));
Next steps
Congratulations! You’ve created and retrieved data from the local database. Check out the following links to see other Amplify DataStore use cases and advanced concepts: