How can Meteor apps work offline?

OfflineMeteor

Offline Problem Overview


This is useful when:

  • the server is down and the client can't connect for real-time sync
  • there is no Internet connectivity
  • the user doesn't want to go online but wants to work with application;

Offline Solutions


Solution 1 - Offline

Yes! This is already implemented in Meteor, for the most part.

If the connection to the server is lost, the client can still function locally. Database writes will appear to succeed on the client and reflect instantly on the screen. Once the connection is re-established Meteor will re-send all the pending method requests to the server and update the client display with the results from the server. This is all the result of latency compensation, being offline is treated like the server just being very slow.

Clients can monitor the reactive 'Meteor.status()' output to see the status of the current connection. For example you could use Meteor.status to drive a popup with a reconnect timer and a 'connect now' button, like gmail.

EDIT: of course, Meteor isn't magic. If you hit 'reload', or navigate away from the page, etc, while offline you'll lose your Meteor session and not being able to start again until you regain network. This is true of all web apps with offline mode, though, so it shouldn't come as a surprise to users of your app.

Solution 2 - Offline

There's another couple of options that may solve the 'if your tab closes, or you reload' issue. I've not tried them yet but look interesting.

https://github.com/awwx/meteor-offline-data:

> Meteor Offline Data > > Home of the Meteor offline data project, implementing an "Offline > Collection" which wraps a Meteor.Collection: > > Data from the server is stored persistently in the browser database, > making it available to the application even if the application starts > up offline. > > Changes made by the user are also saved in the browser database, > preserving them if the browser is closed and reopened. The next time > the application goes online the changes are sent up to the server. > > Updates are reactively shared across browser windows open on the same > application, even while offline.

and https://github.com/GroundMeteor/Meteor-GroundDB:

> Features: > > Light footprint > > Broad browser support Chrome, Safari, Firefox and Internet Explorer 9 > Fallback to normal Meteor.Collection if no localstorage Resume of > changes in collections Resume of methods Works offline updating cross > window tabs Support for SmartCollection Support for offline > client-side only databases Uses EJSON.minify and EJSON.maxify to > compress data in localstorage In the future there will be a customizable conflict handler on the server-side

Solution 3 - Offline

Bottom of the line:

  1. Either the browser can fully save the actual session (every how long? everytime the app requests it because got changes. For such app, every 10 sec is not enough, we need every events). Can we program it in let's say Firefox? (But it would need to save everything (HTML, JS, MinoMongoDB, etc. just for one change!)

  2. Or we have a client side full meteor stack taking care of local stuff (a local app of its own) but somehow communicating its CRUD operations to another online app in another tab or instance of the browser. (That 2nd app would be served by the real remote server) The problem is if such 2 apps can communicate. I suppose browsers would forbid it for security reasons)

Another more creative idea could be: Activate oplog on client's stack. Then, every back-online and constantly when online, the actual client's oplog could be exported/imported in the main app (which is another oplog log),

  1. Unless we can send call() request from the client's meteor full stack to another meteor stack on the server. (Is it possible? Is there some rules about URL domain limitations in meteor)

But it does not fix the possibility of having a full meteor stack on a tablet (I am not aware shuch thing is possible)

Solution 4 - Offline

I am not an expert but let's imagine a solution:

Not on a tablet/cell (not sure we can install a meteor stack on such device), but on desktop, the user needs an offline availability such as point of sale, some transaction logging, a limited or not up-to-date product list, pricing and inventory, etc. (Transactions using stock that is not physically local, should be « to be confirmed (offline order) »  (Locations having that stock could sell even if already reserved by an offline order, that they ar not aware of, because them or the other user is offline, especially if the user having the stock is the one offline)

Beside that, some features could be used only when online (using another Meteor web app)

Of course, not all parts of the application can be used offline: Sensitive record creations, some transactions, searches that need the full collection, etc. The offline features would work through the local machine webserver with a working local full stacked Meteor already installed.

Oplog would sync these offline DB to a mirror collection on the centralized server, one specific DB per user, so not all the big data available offline on user's machine. The idea is to maintain availability of some features. We could otherwise have only one DB for offline transactions of all users, but oplog would sync all these transactions on all user's offline DB. We could POST and clear these records ASAP, but not good for privacy. The best is that client's offline DB – and is mirrored one on the centralized server - would include only records created by that user or info that user could need thus one specific DB per user.

A central server side function would regularly validate and POST these records to the larger all users inclusive centralized DB.

A simple way : All transactions done with local offline meteor app that would post transactions to a webservice when available. (this way, users do not have to manage using 2 applications, going back and forth.)

We could use a concept of 2 invoice numbers : Sale invoice number : generated at transaction time (the document ID?)

Sequential invoice number : for accounting purposes, generated later (when online and for document of 15 to 20 sec. Old. We know for sure all new invoices that created in that period )

The idea here is to have a local meteor stack taking car of local persistance, Oplog syncing with centralized persistance (unless we send asynchrone webservice calls for transactions posting when online, but we loose auto sinc with the larger DB)

(After all, maybe better have 2 applications running: on local, one central served and a way to let these 2 talk together, or an online and an offline app with a comfortable way to direct the user to use the online one in priority and the offline one if offline)

Would be good if the community of more knowledgable people evaluates and document a working way. I did not use yet Meteor, still in the basic learning process.

Thanks,

Marc

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAleksey KulikovView Question on Stackoverflow
Solution 1 - Offlinen1mmyView Answer on Stackoverflow
Solution 2 - OfflinerussellfeeedView Answer on Stackoverflow
Solution 3 - OfflineEMHmark7View Answer on Stackoverflow
Solution 4 - OfflineEMHmark7View Answer on Stackoverflow