OiO.lk Blog Android Save data class into protobuf data store
Android

Save data class into protobuf data store


I am working on an app which is receiving data from an endpoint. I used to save a backup of this data into the Shared Prefrences but as the object is complex the JsonToString and StringToJson serialization is not efficient specifically when there is an update in the data class. In case, the app is updated with an updated data class but the previous app still have the old data stored into the Shared Preferences, I notice some issue to extract them correctly. Despite the fact that it’s easy to play with, the protobuf datastore is a better approach as I would say it’s a good solution in between using shared preferences and use a database.
However, I am encounting errors on complex objects. I suspect it’s the naming convention and/or a missign steps in my approach.

The data class used by retrofit to serialize the Json is looking like the one below:

data class Order(
   val id: Int,
   val name: String,
   val items: List<Item>
)

data class Item(
   val id: Int,
   val name: String,
   val description: String,
   val address: Address
)

data class Address(
   val address: String
   val zip: String
)

So to make protobuf datastore works, I created the proto file:

syntax = "proto3";

option java_package = "com.mcdonalds.app";
option java_multiple_files = true;

message LastOrder {
    Order order = 1;
}

message Order {
    int32 id = 1;
    string name = 2;
    repeated Item items = 3;
}

message Item {
    int32 id = 1;
    string name = 2;
    string description = 3;
    Address address = 4;
}

message Address {
    string address = 1;
    string zip = 2;
}

So the LastOrder class is started to be generated but it complains about Order. I assume it’s a conflict between the data class Order and the Order in the proto file. I am also struggling to understand how the conversion from data class to proto and vice-versa happened. I was used to JsonToString and StringToJson serialization/deserialization.

I created this function:


override suspend fun saveLastOrder(order: Order) {
        try {
            lastOrderStore.updateData { lastOrder ->
                lastOrder.toBuilder().setOrder(order).build()
            }
        } catch (e: IOException) {
            Log.e(TAG, "Save Last Order Exception: " + e.message)
        }

    }

but I am not sure that the data store is able to map all the other class by just passing order.

I have this serializer class:

object LastOrderSerializer : Serializer<LastOrder> {
    override val defaultValue: LastOrder
        get() = LastOrder.getDefaultInstance()

    override suspend fun readFrom(input: InputStream): LastOrder {
        try {
            return LastOrder.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override suspend fun writeTo(t: LastOrder, output: OutputStream) {
        t.writeTo(output)
    }

Any idea on how to handle saving complex data class to data store ?
I find example using string, int… but never on complex object.



You need to sign in to view this answers

Exit mobile version