Proto Datastore allows us to store custom type data. It uses protocol buffers to store data.
In share preference, we can only save data in key-value. DataStore allows us to store data in key-value pair and in form of object as well.
Proto DataStore is one way of DataStore to save data.
Please check my previous blog for datastore and preferences datastore : Preferences DataStore
Setup
Add Dependency
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
plugins { id "com.google.protobuf" version "0.8.12" } dependencies { implementation "androidx.datastore:datastore-core:1.0.0-alpha06" implementation "com.google.protobuf:protobuf-javalite:3.11.0" } protobuf { protoc { artifact = "com.google.protobuf:protoc:3.11.0" } generateProtoTasks { all().each { task -> task.builtins { java { option 'lite' } } } } } |
Define a schema
We have to create a predefined schema in our project. This schema defines the type of object which we wanna store in Proto DataStore.
Suppose, we wanna save user data. We need to create a .proto file in our project. Lets say User.proto. Directory : app/src/main/proto/
Schema :
1 2 3 4 5 6 7 8 9 10 |
syntax = "proto3"; option java_package = "com.example.datasource"; option java_multiple_files = true; message User { string name = 1; int32 id = 2; string email = 3; } |
NOTE: After creating User.proto file, please rebuild your android project.
Create DataStore
Now, define a class which implements Serializer<T> , where T
is the type defined in the proto file. This class will define how to read or write data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
object UserSerializer : Serializer<User> { override val defaultValue: User = User.getDefaultInstance() override fun readFrom(input: InputStream): User { try { return User.parseFrom(input) } catch (exception: InvalidProtocolBufferException) { throw CorruptionException("Cannot read proto.", exception) } } override fun writeTo( t: User, output: OutputStream ) = t.writeTo(output) } |
Use createDataStore() function for creating instance of DataStore.
1 2 3 4 |
val userDataStore: DataStore<User> = createDataStore( fileName = "user.pb", serializer = UserSerializer ) |
Read Data from DataStore
Get user id :
1 2 3 4 |
val userData: Flow<Int> = userDataStore.data .map { user -> user.id } |
Get user name :
1 |
val userData: Flow<String> = userDataStore.data .map { user -> user.name } |
Write Data in DataStore
updateData method is used to save data in Proto DataStore.
1 2 3 4 5 6 7 8 9 |
suspend fun writeData() { userDataStore.updateData { user -> user.toBuilder() .setEmail("test@demo.com") .setId(20) .setName("Ayushi") .build() } } |
To learn more about datastore, check following link : DataStore
Hopefully, this blog will be helpful for you.