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.
Related
I am working on an android e-commerce app and recently I'm having little doubts on some concepts.
Should I include my functions in the client side apk or on the online servers (like Google functions, Amazon lambda)?
For example an user adds an item in his cart
Should I include my code in the client side apk like:
Get the item's price and multiply it with the quantity and then add to the total price of cart.
Or should I just send the data from the client side apk like:
Send the unique ID and quantity to the specific function in online functions
And then put the multiplying and stuff... in the online functions.
Where should I include these calculations?
I think the important thing here is how you're managing state. When the user adds something to their cart, does the app tell the server they've done that? Do they have a cart on the server, with a list of what that user has added so far? Or does it all happen on the user's device, and the server doesn't know anything about the cart until they go to check out?
If the cart is managed on the server, I'd say it's better to let that handle all of the state, and let it tell the device what to display. If the user adds 2 items, tell the server what they've added, and the server can say "your cart contains this" and include the price in that information. It gives you more control, because your server is the source of truth - you're not relying on the device to get it right (which sounds silly but a lot of weird things can happen)
Whatever you do though, don't let the user's device tell the server how much the items cost! If it's calculating the total for the user then fine, so long as it's for display purposes. But when it comes to calculating how much the items cost at checkout, you do that yourself, server-side - take item IDs and counts from the user, nothing else. If they fake a request that says 50 gold watches for $1, you'll be in big trouble!
That might be obvious but I had to put it out there just in case!
It depends on where you're calling that function from. If you're calling that function from somewhere in your front end code, you should include it in your client. If you're calling the function from somewhere in one of your Lambda or Google functions, then you should put it there.
The concept that you might want to learn about is called scope. Wherever a function is in scope, some thing else can call it. You might consider looking up the rules for scope in your specific programming language.
I'm currently working on an android app and I'm using firestore as my storage method. There is a feature in my app that, after a user selects a city, It downloads all it's stores. Given that those stores do not change often, I'm using a flag to know if the stores from one city had been downloaded before, so that I can use cached data instead of server data. My problem is that, if the info of a store changes, a store is added or a store is deleted, the only way the user can get the updated data is to "force download" the city again.
I would like to add a real time listener for a city instead of force downloading. The thing here is that I don't know that, for example, if I have all the stores in cache and suddenly the store "ABCD" changes and triggers my snapshot listener, will it update my cache data as well? If not, is there a way to achieve this?
Thanks!
If you don't have a listener active for the documents of interest that might change, then nothing will change in your local cache. You simply must have that listener active in order to get changes to documents as they happen, and that will cost document reads.
Consider using Firebase Cloud Messaging from your backend to tell your app when data has changed, and it can query that data as needed. That will be a fair amount of work to set up.
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.
My Android app grabs random pictures from a Django server. And in my app, you can vote on the picture.
I want to be able to make sure the user never gets the same picture twice. I already am saving an array of integers that has the picture id locally on the app itself.
My question is, what would be the best/good practice to have the server send only new pictures that haven't been voted on?
I was thinking of sending the server the array of integers so that the server can cross check and send back one that wasn't already voted on, but thinking this could be a problem on a larger scale -> making the server do too many computations.
Thanks in advance!
I don't know much about Django, but either you need to do as you suggested, or you can ask for a random picture, the server responds with the ID it intends to send and your app replies with either yes or no depending on whether it wants that one. The server then either offers another random ID or you accept the picture and it sends it.
Also, use a set instead of an array - you have no interest in order, you just want to avoid duplicates.
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.