3

I'm writing an app, and I would like users to have the ability to sign in across multiple devices and still have their data. My question is, when the user signs out of their account on device X, should I delete the entire database and reload their data from the server when they sign in on device Y? This is an issue for a couple of reasons.

  1. Data is stored on both client and server, at any time the user can delete the data locally, but it will still be on the server (notifying the server every time they delete an item seems expensive, I may be wrong).

  2. It's possible that the user may not have an internet connection when they sign out, so I can't just start a thread to do a last minute sync of the local database state and hope for the best.

  • What happens if a user connects to the system with a new device Z which was not connected to the server before? I assume the entire database is transferred to the client. Does it take too much time to do this transfer whenever a user connects to the system? – Doc Brown Oct 31 '16 at 6:53
  • 1
    It's possible that the user may not have an internet connection when they sign out, so I can't just start a thread to do a last minute sync of the local database state and hope for the best. What's your plan to deal with conflicts produced by Device X (w.o internet) updating items that have been deleted by Device Z (this one had connection and stored the changes at server side)? Which devices prevails? – Laiv Oct 31 '16 at 12:58
  • @DocBrown, it could possibly take a while seeing as there are images involved. – BiGGZ Oct 31 '16 at 13:13
  • @Laiv. In that case, with my current thought process, Device Z would prevail. Any changes made by Device X would be unknown to the server – BiGGZ Oct 31 '16 at 13:15
  • And what's going to happen when device X get internets back? – Laiv Oct 31 '16 at 13:16
2

Edit because I didn't actually answer the question. I do not think that you should delete the data from the users system when they sign out.

I do not know your use case, so I cannot say for sure. But it sounds like, what you really should do, is lazy load your data on request and then cache it locally.

From your question, it sounds like you are eager loading the entire dataset, regardless of if the user needs it all or not.

If you can lazy load (Only load each item when the user requests it), you can create a cache system on the device that will allow frequent access to be quick.

In regards to offline access, I strongly suggest that instead of dealing with situations where Z makes changes after X but Z is online and X is not. If I were making your application, I would strongly push to put the application into a read only offline mode. So if X goes offline, it can read the local data store (or cache) but it cannot make changes or delete records until a connection is established.

This saves you a lot of head aches, and makes your implementation much easier.

Lastly, for detecting changes between the local system and the data in the database, there are two ways to go. Either maintain a modified timestamp on the server for every record. If the record on the system is older, then refresh the cached item. Otherwise leave it. Alternatively you could hash the data, and compare to check for changes. Personally I usually just go the timestamp route, as most items I already want a Created and Updated date anyways.

I hope some of that helps.

  • I would strongly push to put the application into a read only offline mode. So if X goes offline, it can read the local data store (or cache) but it cannot make changes or delete records until a connection is established. – BiGGZ Dec 30 '16 at 21:47
  • This right here is the best/simplest/most straight-forward route. Thanks a lot. My current implementation allows full read/write and tracks two things: 1. The failed transactions and 2. The internet connection status. When a connection is re-established, the data is synced. In addition, if the user signs in on another device, they will be forcfully signed out of the other device(if there is no connection, the sign-out signal is persisted and re-sent when a connection has been established, thus performing a sync opp if necessary) – BiGGZ Dec 30 '16 at 21:54
  • 1
    But this too leaves a lot to be desired because if there is no internet connection on the device being forcefully signed out, there could still be anomalies in that the syncing mechanism will kick in a lot later(or not at all) and the currently signed in device will never know. – BiGGZ Dec 30 '16 at 21:55
  • When you say that they are forcefully signed out. Are you trying to limit a user's ability to access the local dataset if they have signed into another device? Personally, I think this is overkill. I think that only allowing one connection to connect to the server at a time, and putting all other devices into an offline mode should be satisfactory. This also solves your issue of trying to sign out an already offline device, because as far as the user is concerned (and the server) there is no difference. Then you can require another sign in on reconnect. – Blair Jan 1 '17 at 0:07
  • 1
    at the end of the day sir, your sugesstion of making the application read-only when there is no internet connection as opposed to tracking transactions and syncing later really is the answer to my dilemma, thanks a lot – BiGGZ Jan 1 '17 at 6:27
2

If you do a delete / re-download you will do two things:-

  • You will upset users with small data plans.
  • You will lose their data. If I make a change that is not synced it will be lost the next time the system connects.

So, you need to implement a smarter sync.

I'd start by trawling the APIs of whatever language/DB/Frameworks that you use and see if anyone has done this already.

Secondly, I'd see if there is a framework I could use that would enable it.

Thirdly, and very much as a last resort if I failed to find anything, I'd implement a record level "last modified" field as a Date/Time. Then, when you sync, you are only looking to do an update of newer records (what's the newest change in table A on the mobile device, what's the newest change in the remote table A. Do they differ? If so, you need to implement the merge of the data to make sure the most recent changes from both databases are up to date in both databases.

I suspect you will find that there IS a suitable mechanism built in or part of a mainstream framework. It will save you days.

  • Thanks for your answer. Tried to upvote but got told im too new. In line with your third suggestion. What if the server tables have a boolean isSynced column, then on the client side i set up a periodic sync(user specified interval), then when they log in from a different device, i just pull the isSynced=true records? – BiGGZ Oct 31 '16 at 13:18
  • @vernon that doesn't sound like it would support multiple devices. Why not "getChangedSince(date lastSync)" – Richard Tingle Oct 31 '16 at 14:35
  • @Richard Tingle , because its not the actual content of the files that might change, its whether the user has deleted them or not, thats what im trying to track – BiGGZ Oct 31 '16 at 14:43
  • It almost sounds like you are looking for a git-like solution. – voodoo-burger Dec 30 '16 at 14:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.