The Situation: I have a database and a web app that interact to display and update tables of scientific data. My task is to construct a mobile application that will allow users to
The Question: What is the best way to go about authenticating/downloading/storing/uploading the necessary data to administer such an application independent of consistent internet access? If two people adjust the same reading, and one update happens in between syncs, how do I track which tables and values have been altered, and prevent the changes from being lost?
The Current Train of Thought: My current tentative strategy on collision control to maintain a "Sync" table that stores JSON objects representing every online database transaction stored in sessionStorage and have the app continuously verifying its sync prior to uploading data, and checking this object for potential collisions on updates to specific primary keys. I would like to be able to lock tuples when they are in an editing stage, but that seems impossible with inconsistent internet access.
Sorry if this is a bit of a newb question, I'm new to the whole mobile app development thing...
tl;dr How do I prevent asynchronous changes to the database from mobile apps that go on and offline from overwriting/colliding with another individual's changes to the same database? And how do I authenticate users w/o a network connection?
As to synchronization you could have a look at jIO - an open-source library we are working on that can synchronize JSON documents across different types of storages and has a super-simple API.
There are a bunch of connectors available and being worked on (webDav, S3, xwiki, etc) and you can also write your own connector to hook up JIO to whereever you are supplying your JSON data from.
Then on the client you can for example set up a replicate-revision storage using the client localhost and your remote storage as storages:
var jio_instance = jIO.newJio({
"type": "replicaterevision",
"storage_list": [{
"type": "revision",
"sub_storage": {<storage spec for your localhost storage>}
}, {
"type": "revision",
"sub_storage": {<storage spec for your remote storage>}
}]
});
All storages in the storage_list
will automatically be versioned and synchronized. So if a user is offline, retrieves a document, edits and saves it (only to localstorage, as user is offline), jIO will throw a conflict the next time the user tries to access the file when being online, because the current version on remote-storage
and localstorage
differ.
Then it's only a matter of writing a routine to solve any conflicts arising from multiple users editing documents while being online/offline = which version to keep/merge/etc.
Access to documents is fairly straightforward. JSON documents have meta data and attachements and you can use the following commands to modify your JSON documents:
POST > generate a new document
PUT > update existing document
GET > retrieve a document
REMOVE > delete a document
ALLDOCS > retrieve all documents
PUTATTACHEMENT > add an attachment to a document
GETATTACHEMENT > retrieve an attachment from a document
REMOVEATTACHEMENT > delete an attachement from a document
callable like this:
jio_instance.get({"_id":"your_doc_id"}, function (err, response) {
// do something
});
JIO also has a complex-queries
module, which allows to run database like queries on your storages. So you could do something like this:
options = {
query: '(author:"% Doe") AND (format:"pdf")',
limit: [0, 100],
sort_on: [['last_modified', 'descending'], ['creation_date', 'descending']],
select_list: ['title'],
wildcard_character: '%'
};
// run query
jio_instance.allDocs(options, function (error, response) {
// do sth
});
Let me know if you have any questions.
Have you heard about "race condition" [1] in terms of ajax calls? There is a solution [2], how you can make your ajax calls to your server sequential instead of concurrent and thus they are run in sequence after one then another. This works with asyncronous connection, so any other sync thing is not needed.
The trick here is to use jQuery ajaxQueue [3] for that purpose.
My sources:
[1] http://en.wikipedia.org/wiki/Race_condition
[2] How to make all AJAX calls sequential?
[3] http://plugins.jquery.com/ajaxqueue/
For user authentication while not connected to network i will suggest following path:
In point #2 you are downloading identification data via internet access. So obviously you will have to save username and password pair in an encrypted format inside local storage. That is only thing which will help you while authenticating the same user on same device while accessing the application in remote area i.e. in offline mode. Ultimately hand held devices are per user and your application will keep history of that user only; which is I think absolutely fine in such scenario.
For avoiding collision; i will suggest to increase the number of times the device get sync up with main server. If the users are in network and they do some modification to data then background sync operation should sync those changes to main server and other users should get sync up after predefined intervals. More the time you sync up the data; lesser are the chances of conflicts. But again the question remain about the modification happened to data while user is in offline mode. For this we can not do anything. Your conflict management code should have some intelligence like which copy of data should have more preference, i.e. data coming from X user having A security role OR data coming from Y user having B security role or something like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With