6

If I have the following class, how can I save a list of it with Proto DataStore?

data class Tag(
    val id: int,
    val name: String
)

All guides that I saw were teaching how to save only a single object. Is it possible to have a list of it?

Guilherme Oliveira
  • 916
  • 1
  • 11
  • 21

2 Answers2

7

You should consider storing list of content in Room, Even proto-datastore isnt a proper solution to store complex stuff,

If you still want then, I will suggest you to restrict the data stored to 10-15 items

to the code --->

  1. Create your proto file, repeated is used to create list type for Java
message Student {
  string id = 1;
  string name = 2;
}

message ClassRoom {
  string teacher = 1;
  repeated Student students  = 2; // repeated => list
}

  1. Inside your proto-store,
dataStore.updateData { store ->
       store.toBuilder()
      .clearStudents() // clear previous list
      .setAllStudents(students)// add the new list
      .build()
}


if you want example checkout my sample app, read the data/domain layer https://github.com/ch8n/Jetpack-compose-thatsMine

Chetan Gupta
  • 1,477
  • 1
  • 13
  • 22
  • Thank you! For this case, I used Room. Thanks for the explanation. – Guilherme Oliveira Mar 20 '21 at 20:52
  • 1
    Hi Chetan, I'm curious, why do you suggest to restrict the data stored to 10-15 items? – Daniel Weidensdörfer Nov 11 '21 at 12:35
  • 1
    Not a big reason, 1mb is limit for data store, and with data getting serialized and deseralized time will increase with size @DanielWeidensdörfer – Chetan Gupta Nov 11 '21 at 18:57
  • @ChetanGupta Thanks, I get the data limit reason. Will the serialization/deserialization time be significant/noticable on a big dataset? I'm just curious, I don't intend to use protobuffers for big amounts of data. – Daniel Weidensdörfer Nov 12 '21 at 12:59
  • they would be obviously faster than shared preferences, but I'm not sure between sqllite and proto buffer, but I can say protobuff are used on Back End than sqllite. Might me some advantages. @DanielWeidensdörfer – Chetan Gupta Dec 16 '21 at 22:12
  • The reason for limiting the items size to 10-15 is not because of the file size limit (I haven't seen any limit on that anywhere in the documentation, actually). The reason is because you cannot just fetch or update a part of data from a list like you can with SQLite libraries such as Room. This is true for both Proto and Preferences version. So if you have 10 thousand elements and you save them to DataStore and then you want to update 2 of them based on a condition you'll have to fetch the entire list, manipulate it and put it back. Here Room (or any DB solution) will be a way to go – konnovdev May 27 '22 at 06:55
0

You can encode your class object into json string by the help of kotlinx json library and store that string into datastore preference like below ->

@Serializable
data class EmployeeCorporateInfo(
    @SerialName("companyName")
    val companyName: String,
    @SerialName("employeeInfo")
    val employeeInfo: EmployeeInfo,
    @SerialName("firstName")
    val firstName: String,
    @SerialName("id")
    val id: String,
    @SerialName("lastName")
    val lastName: String,
    @SerialName("middleName")
    val middleName: String
)

@Serializable
data class EmployeeCorporates(val corporates:List<EmployeeCorporateInfo>)

Encode into JSON:

val employeeCorporates = EmployeeCorporates(emptyList()) 
val rawCorporate:String = Json.encodeToString(employeeCorporates ))

Store rawCorporate into preference data store. After whenever you need that get from preference data store and decode that string into our class object.

val employeeCorporates = Json.decodeFromString<EmployeeCorporate(rawCorporate)
DaveL17
  • 1,673
  • 7
  • 24
  • 38