How to handle gaps in local cache - android

I have an application that aims to behave like the instagram app. This means:
When the user opens the app, latest content from the local database is displayed, but a request is fired to get the server's latest content. If the server returns such data, the local database gets populated with it and then the UI displays it.
So, how can I handle the gap that this can create between the records that already existed, and the newer ones? Let's say I get 10 items per page from my API, and there are 15 new ones. When the request returns, the latest 10 items get inserted in my local database this leaving a gap of 5 items with the ones that were already there. This could even happen several times if the user doesn't use the app a lot, and the gap could just be huge if they haven't used it in a while, so just firing a lot of request doesn't seem to be the solution.
And the second thing is stale data. Items that have been updated or deleted on the server. I can provide an endpoint to retrieve changes, and soft-delete records so they can still be get but with a "deleted" flag. But the question is: when and how should I request that? It doesn't simply belong in to the "Enter the app -> request latest items" flow. Should I just poll regularly, use some sort of notifications maybe? Then what if the user is offline?
I'm puzzled and I've been googling A LOT lately, and I haven't found a convincing solution. They all are SyncAdapter style stuff.
Thanks.

I'm not sure specific on instagram, but on the app I work on and what I see around other apps, is to delete the feed of local data when you GET the page 0. Then as the user scrolls down, it reloads from internet the next pages.
What I mean by "delete the feed of local data" is, for example:
request is page=0 of friends_recents_photos
onSuccess -> DELETE friends_recents_photos -> INSERT new data
then onScroll -> loadMore
request page=1
onSuccess -> APPEND new data AT end
but that's only the request data of that specific feed, other feeds (e.g. followers), detailed information (e.g. UserData) or cached/downloaded images is kept in cache for fast access.

Related

Android Pagination on server or client side

I'm developing an android app, which will fetch data from my webservice and display it to user. I have a confusion in deciding where to keep pagination(in client side or server side)
My scenario is, I ll take input from the user and make a call to my webservice, to fetch all the data available for the input(response is in Json format) and then, display the data fetched in Recyclerview. I want to display only 50 records initially, then when "show more" button is clicked, the next 50 is displayed.
My data(reponse from webservice) range varies from 0 to 15000 , based on the input from user. And I have other filtering parameters in UI, which will change the rendered data when selected.
So, is it good to fetch all the 15000 records at once and do all kind of processing in client side?
or to fetch 50 records each time when "show more" button is clicked? and to fire new API call whenever filter is changed?
Thanks.
You should never try to fetch such a large number of records in one go, because : 1) your app would have a very slow FRT (First Response Time) 2) the user is unlikely to view more than a couple hundred records at any given time. 3) If the user data (2G/3G/4G) is paid, the user ends up paying for data that he would never see.
So, you should always have pagination on the server side and then your client can request subsequent records as and when needed.
Having said that, network requests would take time and waiting for response every time user clicks on "Show More" would be bad UX as well. So, you need to consider batching requests together and even pre-fetching some data. Here is a nice video for you to see before changing your architecture : https://www.youtube.com/watch?v=3kOx-IPqtqA

LIKE autocompletion too stressful on the database?

I'm writing an android application that has a search feature that needs to autocomplete from a list of stores. This list will only have up to a few thousand stores in it.
My current methodology is to send a LIKE query to the database every few hundred ms after the user has stopped typing and to populate the autocomplete list with these results.
Would using this method be stressful to the database?
It has been suggested to me that this wouldn't work because making continuous calls would be poor for users with a slow connection and that I should load all the stores into memory and filter from there.
At my work I ran into a similar problem a few months back. The contents of a text box filled by the user were supposed to filter their available options to choose from in a list of strings. The list needed to be updated every time the user typed a key so database calls to fetch records that matched their text were being made several times a second.
This ended up being wayy to slow to update as someone was typing, and this was only with several thousand records and with a server that was being accessed on site.
If you want to update as quickly as someone can type, making that many database calls simply won't do. Users will get pretty antsy having to let their phone buffer to type in some text.
In Short: Make one databse call and load it up onto the phone, and run your filter algorithm from there.
Regularly syncing the list of stores from your back end to the user's device and implementing autocomplete locally is the best way to go.
The JobScheduler API provides a flexible way to set constraints on your background syncing processes.

How to reload fresh data from web in background

in my Android app I have a ContactList downloaded from web. I need it in many parts of the app, so i download it at login. This call is paginated, so i need to call the method many times (depends of the contacts number), and I've seen that REST call in 3g connection are sequential.
Users from their app can edit their name, surname, email. So I have to reload the contact list not only to add new ones, but to update users information too.
The solution for this waste of time at login is to save my user array list into a file, at login open the file and use the old list and then, in background, dinamically download new fresh data and change every single user data with the new fresh one. Is this possible? how to do that?
you can use GCM for that which pushes updates to phone as soon as they happen on server. you can load the contacts at login, but as soon as something changes or created on server you can inform the user about it and can only load that Contact.
check link how to implement it
http://developer.android.com/google/gcm/index.html

How to consistently and efficiently refresh a listview feed of content?

I currently have several fragment tabs , each with a feed of user statuses, being I have about a 100 other users posting from their accounts there is constantly new data every few minutes. currently the users only choice is to switch fragments back and fourth to get the entire fragment to reload which sends another http request and returns the new data as well as all the old data the user already had. it just doesnt seem efficient, know there has to be a better way. Can someone give me a overview of the most efficient way to keep this data fresh without having the user switch tabs back and fourth?
Is this where using sqlite and/or services comes into play?
Though some developers and designers argue between if content should be refreshed automatically of not, I argue content like streams shouldn't be refreshed automatically unless you are expecting very less incoming data.
I have used twitter4j to stream tweets and refresh automatically in one of my test app, twitter4j has a listener that lets you know when new tweets are received. First I pushed data into ListView as soon as new feeds were received and it was kind of flashy but, efficient. Then I queued up data until it reached certain threshold and pushed data into ListView, it was bit better. I thought it was good enough but, when I monitored my "Data Usage", i quite realized why I shouldn't refresh automatically.
Now here are some example implementation:
(Suggest) Do some type of polling or I recommend you to implement
push(like GCM) to let your client-side know that there's new content
in the server.
(Option) Use SyncAdapter with server triggered sync
(Recommend) Let user be in control, it's more than okay to use
Pull-to-Refresh pattern like Facebook or ActionBar sync button like
Google+. It will not make UserExperience any bad.
Now here's how your sample request API should be like or you can match your own config:
{
"fromIndex": 0,
"toIndex": 10
...
}
well, i'll try to give you a general overview to see if you can get it without the need of getting into deepest details, an idea it just came to my mind:
1- you need to configure your server to retrieve from an "specific" point of the content or retrieve a token that you will pass to the server (on next HttpRequest) to know from where part of the content or from where "index" start to send the content again.
2- you need to have a Listener (i dont know how you are showing your data but this is the case of a ListView) that tells you when the user is closely to get to the end of the ListView and let't say if there are already 10 elements, in element 7 the Listener should call the method to get more content from the server.
3- Yes, you need to keep the data already retrieve in SQLite temporarily, you can't use SharedPreference to keep it because it probably would be a lot of data and maintain it in memory could be a bad idea, writing a file is not an option here neither, so SQLite is your best friend in this case.
Maybe there would be more problems specifics about what you are trying to achieve but to me in a general perspective, those 3 points should at least help you in the direction to go.

Cache for list of friends / items

I'm looking for a way to cache as much data as possible in my app. Most of this data, are items which are crucial for the following steps, like a list of friends. Depending on the selected friend I show a list with certain items and can send something to this friend.
I would like to cache the list of friends. In such way, that it's not possible to send something to a non-existant friend, which would obviously cause an error. Or maybe the cache could work such that it shows a "invalid cached friend" message and refreshes after it...?
The list of friends will not change very frequently but still can change while the user is using the app.
I also want to cache the items which can be sent to the users. These also will not change very frequently, but it's very important that the user doesn't send non-existent items, and it's of course desirable that they see the newest items, if they were updated on the server side.
It's the same principle like caching items which can be bought, for example. It's critical that the users doon't try to complete a transaction with an invalid item.
I have already done some research, but could only come up with a rough idea so far:
Compare data using hash or timestamp: In this case I don't know at which point to do it? Loading the screen probably doesn't make any sense, since the user would have to wait for the server's response anyways. Maybe a background process? But how often do I run it? How do I synchronize?
Also, I can add an update menu item such that the user can ensure that the data is updated. But it still doesn't solve the problem that the user can try to complete transactions with invalid data (if they don't press the button).
I also found some information about "real time data" and AVIs but I think that's not applicable for my case, my data will change seldomly, but it's required that it's valid, since it's not only informative data, it's transaction determining data.
What is the way to handle this?
I think you are right, you should check the timestamp with the data source (the server).
If that's a peer-to-peer exchange between friends, just before sending your data, request its timestamp from the server. Not so much data, usually close to real time. But there's still some minor probability of sending obsolete data - just "a nanosecond" after an update.
If it's through the server (and why not?), as a bonus, you will have optimistic locking by checking the timestamp on the server and canceling the transaction if the data being sent is obsolete.

Categories

Resources