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?
Related
About Single Sources of Truth Google document said:
Using this model, the database serves as the single source of truth, and other parts of the app access it using our UserRepository. Regardless of whether you use a disk cache, we recommend that your repository designate a data source as the single source of truth for the rest of your app
https://developer.android.com/jetpack/guide?gclid=CjwKCAjwo4mIBhBsEiwAKgzXOH1Pq--Ws1PLzUiSP4RmDE6ByKfEi6mdXu5g86btqveIdJvvrgYuxBoCz8wQAvD_BwE&gclsrc=aw.ds#connect-viewmodel-repository
According to the document I save all data when I fected data from remote server and I only get data from room When I need to use in acitivty(In fact I collect flow which is defined in viewmodel).
It seems so good! It avoids the different data sources mix up together! But actually I found some strange question gradually:
In my App, I have a list that the server may change it(Because we have data manager website that admin can update or delete data). So in order to get the newest list data from server, I must clear all data stored in room and fect data again from remote server. This operation seems redundant: "why could I get data directly from remote server", I mean, I only get data from remote source is also a single sources truth. And also it cause a promble: my app will flash a moment because clear data make list empty and fect data from server make list full!
The most important thing is that it seems like the local data is not necessary because I must stay the newest list from remote server.
Some people may say that save data into room can make us app available offlice. I agree that, But in this place, my item of list is represent a image url, and after click the item, the app will jump to a new activity and display a ImageView base on the url we get from the list. If app offlice, the ImageView couldn't load the url also.
I am so confused I couldn't load all image url(use base64-url to avoid load invalid) in a moment also, because the data is so much. And if I say I need a search function in this list and I need load so much unbelievable data into my room, It seems so unreal and event fantasy!
In brief:
Room is a nessary? Couldnt just fect data from remote?
If room is nessary, how to solve problem I met, do my incorrect useage cause the problem?
Hi #psycongroo as I Understood your problem, and I want to share my experience:
You can handle any error with loading URL with placeholder I mean if you got an error with no Internet connection user will see placeholder, but in general libs like Picasso or Glide can cache images when it`s load one time, so the user will see the Image.
The question about why we need to use room instead of fetch data from remote directly. So from your question I don`t understand why you need to drop your local changes even they are completely new, user can have a low internet connection so he will see an empty list instead of previous data with for example progress indicator. And also if the user doesn't have the internet at all you can show some dialog to explain what the problem but old data is still present. If you are using, for example, RecyclerView you can update data with Paging 3 from google, and they update the only necessary items from your list.
P.S. let me know if that help, or you have another question.
My Android app is fetching data from the web (node.js server).
The user create a list of items (usually 20-30 but it can be up to 60+). For each item I query the server to get information for this item. Once this info is fetched (per item), it won't change anymore but new records will be added as time go by (another server call not related to the previous one).
My question is about either storing this info locally (sqlite?) or fetching this info from the server every time the user asks for it (I remind you the amount of calls).
What should be my guidelines whether to store it locally or not other than "speed"?
You should read about the "offline first" principles.
To summarize, mobile users won't always have a stable internet connection (even no connection at all) and the use of your application should not be dependant on a fulltime internet access.
You should decide which data is elligible for offline storage.
It will mainly depend on what the user is supposed to access most often.
If your Items don't vary, you should persist them locally to act as a cache. Despite the fact that the data mayn't be really big, users will welcome it, as your app will need less Internet usage, which may lead to long waits, timeouts, etc.
You could make use of Retrofit to make the calls to the web service.
When it comes to persisting data locally within an Android application, you can store it in several ways.
First one, the easiest, is to use Shared Preferences. I wouldn't suggest you this time, as you're using some objects.
The second one is to use a raw SQLite database.
However, I'd avoid making SQL queries and give a try to ORM frameworks. In Android, you can find several, such as GreenDAO, ORMLite, and so on. This is the choice you should take. And believe me, initially you might find ORMs quite difficult to understand but, when you learn how do they work and the benefits they provide us, you'll love them.
I'm a self taught android programmer so sorry if this is a newbie question. Does anyone know if there's an easy way to merge two realm database files into one combined realm database? The databases contain the same realmobject types and are mutually exclusive (no overlaps of identical objects).
My goal is this: I have a realm database of a workout "session" that is comprised of a list of objects that the user adds to using a wearable. When the user saves the session, I want to send those saved objects to the phone where it can be combined with all past sessions in a realm database stored on the phone.
I'm able to send the database file from wear to phone as an asset and simply replace the file on the phone (using this sample code https://gist.github.com/tajchert/dc30560891bc6aee76fb), but it seems wasteful to send the entire database every time, and I don't want to lose everything if the wear database gets deleted somehow. I'd rather save only the new data from the current session and then clear out the database on the wearable when a new session is started. That way, I'm only ever sending new data to the wearable data layer.
In general, it is not possible to move Realm objects between Realms. You can use copyFromRealm() and copyToRealm(). Of course, you will need to keep track of which objects, which are already been moved (either my marking them somehow or deleting them).
Another option is to use Realm Mobile Platform (https://realm.io/products/realm-mobile-platform/) which can help you to keep all your devices in-sync.
I'm developing an app that downloads ParseObject's data from server and populate a ListView in Fragment with it.
I read about downloading data by Service and after it's done (some kind of listener?) it would update Fragment and be accessible until user leaves the app (which is fine by me).
On the other hand - I can just store it in Bundle and retrieve it every time I get back to that Fragment, but then I'd need implement Serializable which in this case can be cumbersome: like here
Fragments are held by DrawerLayout so it's really irritating now to see loading bar everytime You change to that Fragment and I'm looking for a solution to change that to improve UX.
What do You suggest? Which approach would be better in that situation? Maybe there are things that I should be aware of before attempting to use any of these?
I think it depends on how often the data is changed on the server.
If only daily/weekly the solution must differ compared to if the data is changed every mins/hours.
If the data is kind of static then you can download it only once, and save it to SharedPreferences, or to a seperate local file or DB.
If it changes kinda often, I'd suggest to use bundles or in memory objects, so when the user reenters the app the data should be downloaded again.
The solution i'd use would be to simply convert the entire list of data to JSON, and then save it in SharedPreferences. This allows for easy reuse of the data when the user goes back to that fragment.
As you aren't saving the data across app close/reopen, a local database is not needed.
I am using parse for chat application in android for storing the data I am using both the server and local database(Parse.enableLocalDatastore()) it is working fine, the problem is with fetching data from the database like if network is not available the data will return from local database and if it is available it will return directly from parse so how can i differentiate between them? should i use query.fromLocalDatastore() method while quering the data or not?
You're going to have to build 2 different queries, one for local data and one for network data, and then figure out which one you want to display on screen.
There are a few scenarios you have to account for :
Server side deletion, addition and update
Client side deletion, addition and update
Not all of these need to be accounted for, only those that make sense for your application.
Keep in mind that when an object is pinned (and not saved to the server), it does not have an objectId, but it does have something called a localId (it's private api but you can see it in the debugger). You can check for the existence of objectId to determine if the object was created locally and has never been saved to the server.