I have a database on Google Cloud Firestore, and I am making an Android app in Kotlin to access it. The database has only one collection, but a lot of documents. At a time a user only needs about 5-6 documents. The reason for online database is that more documents can be added easily in the future. Once downloaded, it is rare that the downloaded document data will get updated. So, after download, I want them to access without Internet.
My problem is that even if the documents are stored locally, to access them I have to set a listener, because of which the code becomes asynchronous, which makes things much complex. So I want to store them locally in a different way so that I can access the data without any delay .
This is how I access a document from cache:
val db = FirebaseFirestore.getInstance().collection("courses")
db.document("doc_name").get(Source.CACHE).addOnCompleteListener { task ->
if (task.isSuccessful) {
// what to write here
// to store the data locally
// if some other method is used ?
} else {
// documents need to be re-downloaded
}
}
My question is what is the best way to store my data and how to implement that best way? Given that all the documents share a similar but very complex structure as shown below.
collection/doc_example/
:
|----string
|
|----string
|
|----map
| |----string
| |----int
|
|----int
|
|----array{size=3, type=int}
|
|----string
|
|----map
| |----int
| |----array{size=variable, type=map}
| |----map
| |----string
| |----int
| |----array{size=variable, type=string}
|
|----array{size=variable, type=string}
|
|----array{size=variable, type=string} /* note - this array is optional */
|
|----array{size=variable, type=map}
|----map
|----string
|----string
|----int
|----string
|----string /* note - this one string is optional */
My question is what is the best way to store my data and how to implement that best way?
If you want to persist data in your phone you could try with SQLite or Room Persistence Library, where you can define a database from this structure you showed us and be able to query it for the stored documents.
This way, after first obtaining the document you can store it in the database. On future attempts to obtain it you should check first if it's stored in your database. If it's not then you can proceed to obtain it from Firestore (and save it locally).
Another resource I've used to store and persist data locally is via Android Shared Preferences. This is IMHO less complex than using SQLite or Room, but it has it's limitations for complex data structures (AFAIK, it can only store primitive data and StringSets)... The good news is that you can save your document as a JSON string and easily store it in your Shared Preferences (actually, your document's structure is really adequate for a JSON format, as it has maps, arrays, etc.).
If using this, you then follow the same principle, and check in your Shared Preferences if the document is there before having to grab it from Firestore.