Understanding the side effects of localdatastore in parse.com API - android

I am making an app that will let user keep notes - simple text entries. I want to persist these to the backend and Parse.com seems to make it easy. While going over their documentation, I came across this:
There are a couple of side effects of enabling the local datastore
that you should be aware of. When enabled, there will only be one
instance of any given ParseObject. For example, imagine you have an
instance of the "GameScore" class with an objectId of "xWMyZ4YEGZ",
and then you issue a ParseQuery for all instances of "GameScore" with
that objectId. The result will be the same instance of the object you
already have in memory.
Say that my class is called NoteEntry. Since the user will create a number of notes, there will be a lot of NoteEntrys. Does the side effect mean that only a single NoteEntry can ever exist in the database?
and
Another side effect is that the current user and current installation
will be stored in the local datastore, so you can persist unsaved
changes to these objects between runs of your app using the methods
below.
I don't even know what that means. What is it saying?
Doc: https://www.parse.com/docs/android_guide#localdatastore

No, that's not the side effect. You can still be dealing with lots of Parse objects, it just means that there will be only one copy of each different object. If you had a NoteEntry object in variable x and later query and that same object is returned, it will be equal to the object in x and not a separate copy of the object.

Related

What approaches should I use to share complex object across any class

On example we have an app that tracks Taxi drivers, a taxi driver log in into application and pick an order to drive for given customer.
In this case we have an Order class that represents a lot of data, it's very important to have access to this object from anywhere while still being able to modify it.
From now we can:
pass it by putting extra data to an intent, but it's not something
that makes code readable, in some cases it won't be a solution
deserialize the object into json and store it into cache, we still
need to constantly update this value which is a headache when more
complex objects are in game, one mistake and god knows when the
mismatch happens
store it into class that extends Application, this
is approach I am testing right now, but I am having doubts about this
as when app crashes / android will release app resources randomly, I am in need to restore given object state using
black magic with cache anyway
This is a problem that I believe is shared across many applications, like Spotify's current playing track, etc.
Are there other approaches?
Try using a sqlite database. In this case, you can access your data anywhere from your app if you create a robust GetOrders API method yourself.
Here is a tutorial of creating a database.
In this case, you will never lose any data if app exits or crashes. Also, it really makes no difference compared with caching your data in memory.

Temporary and static realm objects used together?

I am currently running into some issues regarding the realm database and I don't know what the best practices are to tackle this problem.
So I have setup an app which communicates to a server and gets Post Objects through Retrofit stored into my Realm. This post feed is a core part of my app and I want to keep things locally to stay attractive while being offline. The thing is that I cannot store the entire feed list locally as this would be a massive chunk of memory. But I want to make sure that the User gets this content while scrolling through a recycler-view.
The recycler-view currently only shows local Posts and updates them if refresh is forced. I want to implement a load on scroll mecanism that loads Post objects into it while scrolling but this scroll objects should not be stored locally when the app closes.
I thought of creating an additionally in-memory Realm but there is another problem: A Post Object contains a ForeignKey to a UserObject. When I download this dynamic PostObjects and a UserObject changed over this time on the server I want to be able to reflect this changes to every other User on the local persisten Realm too. (To avoid having 2 different UserObjects for the same User)
My best idea i came up so far is to have a
Boolean field on the PostObjects set to true or false to indicate temporary state or not. After the applications closes I would drop all the temporary entries. Is this a viable solution or do I miss anything? I hope you understand my problem and can help.
Edit: My Realm Database contains two relevant objects:
User
Has a name (primarykey), id (global from server), imageUrls etc..
Post
Has a User who created it, again an id and its data (text, date, images...)
Edit2 : What I really need is a type of in-memory Realm that allows me on start up to clone another realm that is used to have data in case of no connectivity. Before the in-memory realm gets deleted I would then override the offline realm with the 5-10 last post entries of the temporary realm. Is such a thing possible?

Questions about the LocalDataStore in Parse

I am developing in iOS with Parse. My app required offline operation, so I had developed my own solution. However, Parse's introduction of the LocalDataStore obviates the need for my own solution. Since this is not released in iOS yet, I can only rely on documentation to prepare for this. I asked these questions on the Parse forum a week ago and the questions have been completely ignored by Parse. Can anyone answer these via experience with the Android version?
1) Objects pointed to by pointers and PFRelations will be pinned along with the pinned object. (That's correct, right?) Will PFFiles be pinned along with the object? Will the file data be locally available?
2) When a pinned object is modified, you have to SaveEventually it to push the changes to the Server, right? Does a Save on a pinned object save locally? Or does it do an "on-line" save?
3) When changes occur elsewhere to a pinned object, how do those changes get propagated to the pinned object in the LocalDataStore? Does the programmer have to explicit fetch the changes, or will it happen automatically?
4) Does the concept of logging in apply to the LDS? Do the ACLs operate in the LDS? Or does the local code have access to all objects in the LDS?
-Bob
I can give a basic answer from the Android side, but keep in mind the details may change as the Parse.com iOS version of LDS is released. My answers below come direct from the API docs are are bolded where I quote directly.
Let's go point by point:
1) Objects pointed to by pointers and PFRelations will be pinned along with the pinned object. (That's correct, right?) Will PFFiles be pinned along with the object? Will the file data be locally available?
Yes. From the Android docs: "Pinning a ParseObject is recursive, just like saving, so any objects that are pointed to by the one you are pinning will also be pinned."
2) When a pinned object is modified, you have to SaveEventually it to push the changes to the Server, right? Does a Save on a pinned object save locally? Or does it do an "on-line" save?
Again, from the Android docs this appears to be Yes. "Once you've saved some changes locally, there are a few different ways you can save those changes back to Parse over the network. The easiest way to do this is with saveEventually. When you call saveEventually on a ParseObject, it will be pinned until it can be saved. The SDK will make sure to save the object the next time the network is available."
3) When changes occur elsewhere to a pinned object, how do those changes get propagated to the pinned object in the LocalDataStore? Does the programmer have to explicit fetch the changes, or will it happen automatically?
The Android docs are pretty quiet about this process, but it's a safe bet you will have to query the server to synchronize the local datastore, the same way you do now when you have a local instance of an object after a query. That's all all the local data store is - a very persistent version of queried data.
4) Does the concept of logging in apply to the LDS? Do the ACLs operate in the LDS? Or does the local code have access to all objects in the LDS?
Logging in still applies, as does ACLs, as far as I can tell. The object permissions are still required for the local data. I haven't confirmed this with a test project in Eclipse, but the docs allude to this being the case.
A final note: The CEO of Parse, Ilya Sukhar, weighed in on the Google Group 3 days ago saying the iOS LDS is definitely on it's way. Here's hoping it's soon!

Android app data storage design

I'm working on an Android app for homework management. I'm a senior in college, so my experience on larger projects is very limited, but I'd like to design all parts of this app well instead of just throwing something together. This includes the way data is stored.
We have two main objects/entities: Task and Subject. Even if someone uses the app for the whole time they're in college and never deletes anything, I'm guessing there would be a maximum of a few thousand tasks and a couple hundred subjects (not all subjects would be shown at once). The initial version of the app won't sync data with a server, but this is a definite possibility in the future, so I'd like to design with that in mind. We might also have an option for users to send tasks to each other.
Here are my questions:
Would a SQLite database be the best option for storing the amount of data we're likely to have, or would something like serializing it to XML or JSON then loading it into memory when the app starts work?
I'm used to thinking in terms of objects. This means that if I use a database and it has a Task table and a Subject table, my first instinct is to convert each database table row into a corresponding object for viewing/editing. (The objects' setters would contain validation logic.) Is this a good/helpful/necessary way to think? If not, what is the alternative?
Thanks for your help!
This question is broad so may comments below may not be 100% correct as I don't have all the information about your system.
SQLite is better suited for storing thousands of records than files (be it JSON or XML). This is especially true if your data is not static, i.e. will be changed during the usage of your app (which is the case for you, I believe). You can take advantage of existing functionality for records inserts, updates, deletions, using indexes, etc.
Yes, you generally create objects similar to your database. But you don't usually need to convert each and every record from the database into your objects. You usually query the database for a limited number of objects, depending on what you want to show in the UI. Of course, if you need to show all, let's say, tasks, you need to get them all.
1. Would a SQLite database be the best option for storing the amount of data we're likely to have, or would something like serializing it to XML or JSON then loading it into memory when the app starts work?
Yes SQlite will be the option for you.It will give you a structured format and in future if you want to access data from remote end the same structure of tables can be used without much change in the code.
2. I'm used to thinking in terms of objects. This means that if I use a database and it has a Task table and a Subject table, my first instinct is to convert each database table row into a corresponding object for viewing/editing. (The objects' setters would contain validation logic.) Is this a good/helpful/necessary way to think? If not, what is the alternative?
you can simply execute queries to manipulate data.
But dont forget to encryt your database if you storing it in mobile itself.

How do I combine usage of db4o to store data and Lucene to index data for fast search?

I'm new to both db4o and Lucene.
Currently I'm using db4o to persist my data on an Android app. I need the capability to perform quick searches, as well as provide suggestions to the user (e.g., auto complete suggestions).
An SO poster mentioned using Lucene to index data and db4o to store it.
Has anyone implemented this approach ? If yes, I would appreciate if they share the overall approach? What are the alternatives?
I used Lucene to extract keywords from items to be stored in the database and store what I call 'keyword extension' objects that point to the corresponding domain objects. This made the domain objects findable by keyword (also allowing for stemming), and separated the keywords concerns. The database was built from a large static dataset (the USDA food nutrient database), so I didn't need to worry about changes during runtime. Thus this solution is limited in its current form ...
The first part of the solution was to write a small chunk of code that takes some text and extracts both the keywords and corresponding stems (using Lucene's 'Snowball' stemming) into a map. You use this to extract the keywords/stems from some domain objects that you are storing in the database. I kept the original keywords around so that I could create some sort of statistics on the searches made.
The second part was to construct objects I called 'keyword extensions' that store the stems as an array and the corresponding keywords as another array and have a pointer to the corresponding domain objects that had the keywords (I used arrays because they work more easily with DB4O). I also subclassed my KeywordExtension class to correspond to the particular domain objects's type - so for example I was storing a 'Nutrient' domain object and a corresponding 'NutrientKeywordExtension' object.
The third part is to collect the user's entered search text, again use the stemmer to extract the stems, and search for the NutrientKeywordExtension objects with those stems. You can then grab the Nutrient objects that those extensions point to, and finally present them as search results.
As I said, my database was static - it's created the first time the application runs. In a dynamic database, you would need to worry about keeping the nutrients and corresponding keyword extensions in sync. One solution would be to merge the nutrient and nutrient keyword extension into one class if you don't mind having that stuff inside your domain objects (I don't like this). Otherwise, you need to account for keyword extensions every time your create/edit/delete your domain objects.
I hope this limited example helps.

Categories

Resources