52

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;
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
Aleksey Kulikov
  • 625
  • 1
  • 5
  • 7
  • Not out of the box, of course it's possible to implement an entire offline solution, but that's thousands of lines of code – Raynos Apr 13 '12 at 06:37
  • This is partly being addressed by the appcache coming soon: http://devel-docs.meteor.com/#appcache (at least the HTML5 cache manifest). Looking good! – Vindberg Mar 12 '13 at 11:48
  • What if One needs to develop a full offline mobile app? [My Question](http://stackoverflow.com/questions/27893600/meteor-for-non-internet-mobile-app) on this is unanswered. Anyone with insights. – sçuçu Jan 12 '15 at 04:55

4 Answers4

55

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.

n1mmy
  • 2,489
  • 1
  • 19
  • 15
  • 31
    It would be interesting to store dirty records on the client in LocalStorage when the connection is unavailable so that in case the local page state is lost they can be recovered. I'd like to see this functionality in meteor. I'm also really interested in exploring ways to store the entire data set locally (possibly as a file in the application cache manifest) so that the app can be reopened and used while offline, but this is a difficult requirement. – Eric Drechsel Apr 13 '12 at 22:39
  • 6
    I developed a library for allows your Backbone.js app to work offline with the same algorithm. https://github.com/Ask11/backbone.offline – Aleksey Kulikov Apr 14 '12 at 10:56
  • 1
    I added this pull: https://github.com/meteor/meteor/pull/20 this adds in the work to get us a manifest to store JS and CSS and the HTML offline. I will be working through the process of getting offline storage and other changes to make the application full HTML first so non js users can see the site but also so it can be used offline fully. – jonathanKingston Apr 14 '12 at 22:08
  • 3
    Aleksey, your backbone.offline storage adapter is one of the most interesting implementations I found while researching offline apps. I had the idea to use the application cache manifest to cache the initial data and then only store dirty items in LocalStorage, to get around the [2.5M character limit](http://dev-test.nemikor.com/web-storage/support-test/) on localStorage. I haven't tested this idea but what do you think? – Eric Drechsel Apr 14 '12 at 22:08
  • Regarding the latency compensation feature, when an update fails due to any reason (server down, etc.) is the update automatically reverted on the client? Moreover, in the case where the client is offline, the user would think that any changes are indeed saved, so I guess it should be made clear to the user that changes are **pending**. – Panagiotis Panagi Apr 15 '12 at 08:48
  • @EricDrechsel Thank you :) I think 2.5mb is enough for any text information. Book "War and Peace" is 3.14mb but it's a very big text. When you're storing specific information like books than your idea sounds nice. I'd like to see your implementation and we could chat about details in skype. – Aleksey Kulikov Apr 16 '12 at 17:00
  • Eric / Aleksey, did you come to any conclusions about using localStorage for storing only dirty items, loading remote data via the cache manifest? Interesting idea! – Winston Fassett Oct 11 '12 at 05:21
  • [SyncIt](https://github.com/forbesmyester/SyncIt) is one of these "edit locally then apply to server" libraries, but it's thought about as offline first. Disclosure: I wrote it. – Forbesmyester Nov 24 '13 at 10:46
13

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

russellfeeed
  • 617
  • 8
  • 10
0

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),

3) 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)

EMHmark7
  • 87
  • 8
-1

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

EMHmark7
  • 87
  • 8
  • 1
    While your answer is somewhat comprehensive, I think you are missing the point a little bit. – Dave Jan 31 '15 at 19:57
  • Sure, I am evaluating the possibilities but not sure what the best solution is. (By the way, I maybe updated my post since you read it) Would be glad to get precisions on the point I am missing. Thanks anyway. – EMHmark7 Jan 31 '15 at 20:02