syncing between phone and web algorithm - android

i have a simple note application in two platform, One in mobile(Android & iOS) and other one is web based. I want that this two sync.
My problem is that: How i can determine that which version of a note(android or web) is newer and that text has to be sync? In fact, I need a sync algorithm. If i use timestamp, if users date time in his phone goes to wrong date time, syncing system throws to problem. I want newest edit syncs to all clients.
For example if mobile app were offline and make some changes, In the same time we made changes in server in the same note and when mobile App goes online, which of this changes should be kept? What is the solution?
In the end, What is the best method for this? I want to have best sync method

Clients shouldn't use their local time. Only the server has the right time. Clients have timezone which they can use to show appropriate time to the user. Roughly speaking sync algorithm could look like this:
Client A edits a X note and sends event(request) to the server that the note was updated.
The server receives event and updates timestamp of the message. Then it broadcasts new event that the note X was updated
Client B receives event (with updated note and timestamp) from server and shows to the user updated note with appropriate time.

Related

Android Time Synchronization in UTC

I have an application that relies heavily on current timestamps. Currently, when user submits a request, I get the current timestamp in UTC using System.currentTimeMillis(). While this works fine, it becomes a problem when the user starts manipulating their Date/Time on their device and would result as inaccurate timestamps.
Why do it on the client then? Why not just handle it on the server? Well, my application needs to work offline. All my requests get pushed into a jobQueue when connectivity to the internet is unavailable. In these cases, I must have the original time wherein the user did the action so if I submit a request at 4:02pm, but due to network problems, server will only receive it around 7:30pm, server MUST know that I sent the request at 4:02pm.
Now what options have I considered?
Upon user login, I sync the device time with the server time and store that time locally. If any user manipulation occurs while the user is logged in, I'll have a BroadcastReceiver listening in onto any intents of Date/Time manipulation, then store the offset so that whenever a user submits a request, I will calculate the synced time with the offset to ensure the timestamp is accurate.
Have a server sync api done in the backend and set up a service within my application to continuously sync up with the server time and look for any drift while also listening in onto any user manipulation.
Use push notifications and listen downstream for time synchronization adjustments while also listening onto any user manipulation.
I could also make use of the NTP servers to synchronize time with my device.
I'm not entirely sure which would be the most optimal (assuming I have listed down all the possible solutions). If there are other solutions I haven't thought of, please let me know.
P.S. If I happen to use the BroadcastReceiver to listen onto any datetime manipulation on the device, how would I even calculate the offset in that?
It has been some time since I asked this question and there hasn't been any elegant answers to the problem so after some research and some trial and error, I decided to take the NTP route and after some digging around, I found a nice library that does the entire thing for you.
It can be found here:
NTP TRUE TIME
Credits to these guys who had made life a lot easier.
You must sync with the ntp servers just once and from there on, they will calculate the Delta for us giving us accurate UTC regardless of SystemClock time.
For time synchronization you can implement like getting time zone from server. Once we have timzone we can get the current time of server.

android notify User on when his data changes in the server

We are working on app which is for fixing their appointment with a doctor. We will have to notify the user on that date by saying if the doctor is available or not.
How can we notify the user when the data changes in the server?
The usual workflow for sending push messages from your server to the application, is the Google Cloud Messaging, or the so-called Push Notification in Android.
Simply put, you send your message to the Google and the Google will notify your application. The actual heavily lifting is done by the Google Play Services Library and its corresponding application, which is installed on every android device. For more information on how to implement it, you may refer to the following links.
Official Documentation on Cloud Messaging
Android Push Notification Tutorial
I used http://pusher.com/ "Pusher" for a doc app a couple years ago. It was easy to do and light weight.
Simplest way I would believe is through a polling technique. However, it would not work for real time updates as there is an update interval. Depending on your application's requirements, this might work!
In order to do that.
You would have to publish a web service which would provide a Unix
timestamp. e.g. https://Your-base-url/status.aspx
Each time there is any change on the server, you change the value to a new one on the server.
Your Android device will poll that web service(status) each say 60 seconds
to see if there is an update.
The device would save the timestamp in his device and would check
whether the two timestamps match.
If not, then he will call the relevant web services to get updated
data.
However, you should note that the Android device will only get to know whenever it polls. So, the device might not know the update until his next polling cycle.
The most accurate way is to maintain a persistent Socket connection with your server at all times. Whenever an update occurs, you can immediately send the updates to the device via the open socket. However, this is more complicated as you will have to deal with the socket connections.
GCM uses socket connections internally. Therefore, a solution including GCM is an easier approach.

Keeping an app's internal time in sync

Disclaimer: I am a backend developer, and I have no idea of what happens inside an Android or iOS app, so please bear with me.
In a specific use case of our platform we would need all client applications (Android and iOS) to keep an internal timer accurate and in sync with an external source of time (so that they can accurately timestamp messages sent between one another). Is this possible at all (using, for example, an NTP client or a different / better technique)?
When the client connects to the server it can fetch what the server's reference time source is. Once it has obtained this it can calculate and store the difference between the server's time and the device's time.
Then when the client needs to do something based on the time* on the handset it takes the server's time into consideration when doing whatever it needs to do such as schedule a timer or whatever.
*You can't really do anything based on time in iOS, only if the app is in the foreground. An exception is posting a local notification. Its not possible to schedule a timer for example if the app is in the background.
As per Martin H, you could use an offset from the device's internal time. The client device will probably be within a second of current time if the user has not manually set the time (which does happen - I just read about a user that changed her date/time to tomorrow to get a reward in a game).
I have dealt with this in a time-based app by using the device time. The client and server validate against server time when communicating with the server.
For example, when the client and server communicate, the server can validate the client time against server time. If the user time is off by more than 'x' minutes, the server sends back an error message.
It will be difficult to keep all clients within a few milliseconds of each other. One idea is to use the server to coordinate messages (messages are not sent between devices, but to the server, which then sends the message on). Then, you can use the received time at the server as the basis for the message time.

notify iOS & Android on data change on server

I'm creating mobile application for iOS and Android. The problem is when any data has changed on server, I cannot notify mobile devices.
I have found 3 solutions, each have minus and pluses.
Use push notifications. Since iOS always shows a notification to user this is not a solution at all. Also I cannot know if the notification will go to device or when it will.
For every X seconds ask server if any change exists. I don't want to do that, because creating too many HTTP connections and closing them is not a good idea I think. Also if the data is changed right after the device asks, the info change on device will occur late.
Use web socket. My application's one time usage expectation is ~2 minutes. So web socket looks like a good choice, because app will be terminated or go to background state quickly and battery consume won't be much. Also all the server side data changes will come to the device just in time. But I don't know much about web socket. Is my opinion acceptable? Also how many concurrent connections can be done by my server. Is it a question too.
Here are my all solutions.
The document would suggest assumption 1. above is incorrect.
If you read the The Notification Payload section, you'll come across this;
The aps dictionary can also contain the content-available property. The content-available property with a value of 1 lets the remote notification act as a “silent” notification. When a silent notification arrives, iOS wakes up your app in the background so that you can get new data from your server or do background information processing. Users aren’t told about the new or changed information that results from a silent notification, but they can find out about it the next time they open your app.
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
I think for the most part this depends on what your app is doing.
I would say you should use a combination of #1 and #2.
2 - At the very base level if you need information from the server you are going to have to make a request. If this information needs to be up to date then you can proceed to make a request for the information when the ViewController is loaded. If you need this information to update as the ViewController is loaded then you will need to make subsequent requests every X seconds... In addition to this if your user is interacting with this data and sending an update to the server you can check at this point if the data is up to date and alert the user as well as return the current data.
1 - Push Notifications operate off of the 'send and forget' protocol. The notification is sent and is not verified if it is received or not. This is used as a supplement to #2 and is 'nice' but should not be depended upon.
Push notification is the intended way (from both Google through Google Cloud Messaging, and Apple through Apple Push Notification Service).
Both option 2 and 3 are frowned upon as they affect battery life, and they are unnecessary as most cases scenarios can be covered by push notifications.

Get accurate time from android/iphone to server

We have an android(or iphone) client we are developing. The client allows the android user to send entries to a server which we also develop. If the client does not have data services (GPRS) at the moment the user sends the entry to the server, the client also supports saving the entry to an offline database and sending it later to the server.
One important aspect of the whole process is accuracy of the timestamps on which the user sent the entry to the server (whether the entry is made in real time or sent by the client from the offline database)
When available on the client, we get a GPS location and are able to use the GPS timestamp to send that to the server (or save the GPS timestamp on the offline DB and send it later to the server). However if the user has turned off the GPS (and all other location services), the device will not have a GPS fix and therefore the server can not determine accurately when an entry was made.
We can not use the local device clock as the user may change the clock to make entries on different times than they actually occurred (these entries are part of the users salary so he might have an interest to "fix" them).
So basically I am searching for a way to determine as best I can the time some entry was made when I can not trust the internal clock of the mobile. The algorithm should support both entries sent in real time or entries sent from an offline DB. the algorithm should also support cases where the user changes the time of the mobile, turns the mobile on/off, turns the GPS on/off while the application is running on the mobile etc...
Few ideas that I thought of:
Although I can not trust the mobile's time, it can still perform as a stop watch:
Have a class that will loop until the application exists, the loop will sleep 1 second and increase an internal clock variable by 1 second. On every GPS location my code gets we update the internal clock variable. This way I have an absolute clock that came from outside the device (from the GPS) and when the client sends an entry to the server, we can use the internal clock as an absolute time.
PROS: the user can not modify this clock as it is only updated when we get a location from the GPS
CONS: the application needs at least one GPS fix before the user can make any reliable entries
I can take advantage of the fact that the server has an accurate clock which is correct. If the client would send to the server info that the age of the entry is 10 minutes, the server could use its internal time and know the exact time the entry was made on.
The biggest problem is how to know the entry age? I thought about saving the entries to the offline DB with an age of 0, then every 1 second increase the age of the entry in the DB. The problem is that if the app is closed and/or the device is off this will now happen
This is where I am currently stuck. Any ideas on how to solve this are more than welcome
Thanks
Here's how I handle this issue for iPhone. When the app starts, I call my server and ask for the current GMT time (you could also call a public NTP server if you preferred). I then compare it to the system time. If it is different by more than X then I popup a message saying, sorry your system time is wrong so you can't use the app until you fix this. I then monitor for the user changing the system time while the app is running and if they do that, then I do the compare again (and popup the error message if the time is off by more than X). This ensures that their system time is always correct (within some reasonable allowance) and you can trust [NSDate date]. However, this solution does require a valid network connection. If this solution works for you, I can post the sample code.
i think i am going to combine Jules and Joel's answers into one solution which will provide for my needs the best solution:
since the user might change the clock when the mobile doed not have GPRS, just detecting the time change event will not help us as we can not validate at that moment the new time is correct.
As Joel recommended i will pull the time from my server when my application is started (at that point i still must have communications with the server or else my application will not start). The time pulled from the server along with the current device upTime will be saved.
when the user wants to make an entry i will calculate the current time using (Server Base Time + Current UpTime - Base UpTime). this way i will have an independent source of time regardless of the current clock of the device
this will defenitly work on android
on iPhone we will try to use something out of http://www.cocoadev.com/index.pl?FindingUptime to get the upTime
Jules & Joel, thanks for your answers!
Look into android.os.SystemClock. Specifically, elapsedRealtime() returns a time since the phone was switched on, which is not affected if the clock is changed by the user.
You can correlate times in event the phone is switched off by having code that runs when it is switched on and checks the realtime clock. As the clock can't be changed when the phone is off, I suspect you could use this to put together a system that will catch any simple attempts at cheating. (If the user roots the phone all bets are off -- they could modify the behaviour of the APIs from under you).
Running code every second will kill the phone's battery life. Most phones would be unlikely to last a day if you did this.

Categories

Resources