Meteor-Community-Packages / ground-db

GroundDB is a thin layer providing Meteor offline database and methods
https://atmospherejs.com/ground/db
MIT License
569 stars 76 forks source link

Persist data on Cordova #97

Open rafaelquintanilha opened 9 years ago

rafaelquintanilha commented 9 years ago

I've been working with this package for a while and successfully set a example when I was able to persist the data offline when in the web browser. However, I'm finding a hard time to replicate this behavior in mobile - which was my primary goal since the beginning.

Currently I am able to retrieve all information up-to-date when offline, i.e., make change online, go offline and see everything as it should be when online. If changes are made and a connection is detected, the app syncs and everything works fine.

The problem is when I am working offline, the app is closed and reopened later. All changes are lost in this scenario.

Anyone had any luck with this situation? I'm definitely needing to surpass this. How can I assure some change was saved in local database and retrieve it later?

Thanks!

jms301 commented 9 years ago

To be honest this sounds like the behaviour of meteor without GroundDB are you sure GroundDB is set up correctly? I've had the scenario you're talking about working on Android OK.

rafaelquintanilha commented 9 years ago

Hey @jms301, thanks for your response.

Well, of course I might be wrong but I've tried too many times that I don't know what this could be. I'm subscribing to the publishing functions on startup and grounding the collections as instructed. I've even disabled for now the template-level subscriptions that I've been using.

Are you doing something different? Maybe you could share some code snippets or give me some guidance, I'd be very grateful.

jms301 commented 9 years ago

My projects code is Open Source so go nuts: https://github.com/jms301/todo-play/blob/master/packages/todolists/todolists.js#L15 happy to look at any code snippets.

rafaelquintanilha commented 9 years ago

Thanks again @jms301 .

Well, this is weird. Playing around with your code, the only thing you seemed to do different (apart for creating a package) was to wrap the Ground() call into a Meteor.isCordova function.

I tried the same thing, again without success. But I have a clue now: when I run the app for the first time and go offline, nothing seems to be grounded. However, if I go online, start the app again, close the app, go offline and start the app again, the changes are there.

So it seems to me that there is something on startup that is "saving" the data. Of course if I am offline, I am losing the data before "saving" it on startup. The problem is that my code is pretty straightforward. Here it goes:

/collections/safristas.js

...
Safristas = new Meteor.Collection("Safristas");
Safristas.attachSchema(SafristasSchema);
...

/collections/apontamentos.js

...
Apontamentos = new Meteor.Collection("Apontamentos");
Apontamentos.attachSchema(ApontamentosSchema);
...

/lib/init.js

Meteor.startup(function() {
  if ( Meteor.isCordova ) {
    Ground.Collection(Safristas);
    Ground.Collection(Apontamentos);
    alert("Grounding");
  }

  if ( Meteor.isClient ) {
    Meteor.subscribe("safristas");
    Meteor.subscribe("apontamentos");
    alert("Subscribing");
  }

});

And then I just perform the findings like normal and the changes trough methods (defined in the same place the collections are defined). No more subscriptions are defined, not even in the router.

The project works perfect when online but I can't get persistence when offline. Any ideas what I am missing here?

jms301 commented 9 years ago

Very odd it looks generally OK to me, is your publication "Safristas" capitalized? That is different from the docs but should work fine...

Although what is

Safristas.attachSchema(SafristasSchema);

If you have something else modifying the way Meteor collections work maybe it is conflicting with Ground:db?

rafaelquintanilha commented 9 years ago

My /server/publications.js is pretty straightforward:

Meteor.publish('safristas', function() {
  return Safristas.find();
});

Meteor.publish('apontamentos', function() {
  return Apontamentos.find();
});

Regarding the Schema, I thought about it as well. But even with the .attachSchema() method commented out the problem persists.

Just tried here again and the error keeps happening: the data is being grounded only when I relaunch the app (I am monitoring in Settings >> Apps >> MyApp, where it shows the total amount of storage used by the app).

Is there any way to "force" the data to be grounded? Something like myGroundedCollection.groundData()? I looked the source code without much luck.

jms301 commented 9 years ago

Hmm perhaps try removing the collection2 package or whatever it is that's modified Meteor.Collections.

Oh wait you're not using insert / update but other methods? I think then you have to add those in to be cached into local storage see the ground db docs:

// This is how grounddb uses this internally
  Ground.methodResume([
    '/' + self.name + '/insert',
    '/' + self.name + '/remove',
    '/' + self.name + '/update'
  ], self.connection);

I've not experimented with this yet myself.

rafaelquintanilha commented 9 years ago

Here's an example of method I am using:

Meteor.methods({
  updatePhoto: function(obj) {
    check(obj, {
      id: String,
      photo: String
    });

    return Safristas.update(obj.id, { $set: {photo: obj.photo} });
  }
});

I did what you said and added it with no luck:

if ( Meteor.isClient ) {
Ground.methodResume([
  '/' + "updatePhoto" + '/insert',
  '/' + "updatePhoto" + '/remove',
  '/' + "updatePhoto" + '/update'
]);
}

But I'm not sure if this is the correct way of use as it's not so explicit in the docs.

I'll have a shot removing all sorts of collection modifiers although it doesn't seem to be a problem to me. @raix could confirm this?

Thanks again mate for your patience!

raix commented 9 years ago
if ( Meteor.isClient ) {
Ground.methodResume([
  'updatePhoto'
]);
}
vieko commented 9 years ago

curious if this resolved your issue @rafaelquintanilha

rafaelquintanilha commented 9 years ago

@vieko I decided to set a new test project up, stripping all packages until figure out what was the problem. Turns out that @jms301 was right indeed, without the collection2 package everything works fine. In order to use methods, the Ground.methodResume() is also necessary.

I'll make it a repo and maybe write a tutorial once this scenario seems to be pretty common and yet poorly documented.

rafaelquintanilha commented 9 years ago

As promised, just created a tutorial of how to set a offline app properly. See a repo here. Many thanks to @jms301 and @raix. Any feedback appreciated.

Wenape commented 9 years ago

@rafaelquintanilha Thanks for the tutorial, helped me a lot. I know that if you uninstall an app, GroundDB data obviously gets deleted as well, but what about an app update? And I mean an update directly from the app store or play store, not just a hot code push. Does the GroundDB data still persist?

lanmower commented 7 years ago

This is open since 2015? is ground db still alive?