Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Offline/Online Database Authentication/Synchronization from jQuery Mobile

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

  1. Authenticate and Identify Themselves Offline for Tracking Purposes (using predefined but dynamic user-accounts and permissions stored in the cache)
  2. Download Identification Data for Work in the Field (with internet access)
  3. Make and Store Observations in the Field (without internet access)
  4. Synchronize Observations into an Online Database at a later time

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?

like image 653
XaxD Avatar asked Aug 27 '13 15:08

XaxD


3 Answers

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-storageand 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.

like image 91
frequent Avatar answered Nov 15 '22 22:11

frequent


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/

like image 21
mico Avatar answered Nov 15 '22 23:11

mico


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.

like image 2
vijayP Avatar answered Nov 16 '22 00:11

vijayP