Meteor-Community-Packages / ground-db

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

Ground DB v2 suddenly empty #186

Open Taxel opened 7 years ago

Taxel commented 7 years ago

Hi @raix , I am having a big problem with ground db. First, I used the atmosphere version (0.3.15?), now I updated to ground:db 2.0.0-rc.6, hoping this would fix my problem.

I am using Meteor React and this is the code for the main container, which is supposed to block other pages from loading before the offline database has been populated (later I will add a check if the Ground DB has already been loaded at an earlier session)

let fullyLoaded = new ReactiveVar(false);
let subscribed = false;
let subscribedOnce = false;
let checking = false;

export default createContainer(() => {

    if(Meteor.status().connected && !subscribedOnce && !subscribed){
        subscribed = true;
        console.log("subscribing");
        Meteor.subscribe("localization",
            ()=> {
                localizationGrounded.keep(Localization.findNonGrounded());
                console.log("everything has been loaded once.");
                console.log("Localization count after subscription: " + Localization.find().fetch().length);

                fullyLoaded.set(true);
                subscribed = false;
                subscribedOnce = true;
            }

        );
    }
    if(fullyLoaded.get()){
        console.log("Localization Count: " + Localization.find().fetch().length)
    }
    return {
        isLoggedIn: !!Meteor.userId(),
        isLoading: !fullyLoaded.get() || subscribed,

    };
}, Main);

This code is supposed to subscribe to "localization" if it hasn't been loaded already. The Localization Collection is implemented as follows, the find() and findOne() method has been overwritten to call find() for the grounded DB:

export const Localization = new Mongo.Collection('localization');

if(Meteor.isClient){
    export let localizationGrounded = new Ground.Collection('localization', {
        cleanupLocalData: false
    });

    //rename find() to findNonGrounded
    Localization.findNonGrounded = Localization.find;

    localizationGrounded.observeSource(Localization.findNonGrounded());

    Localization.find = function(...args){
        console.log("finding from ground db");
        return localizationGrounded.find(...args);
    };

    Localization.findOne = function(...args){
        console.log("finding one from ground db");
        return localizationGrounded.findOne(...args);
    }
}

This however produces the following output:

subscribing
everything has been loaded once
finding from ground db
Localization count after subscription: 28
finding from ground db
Localization count: 28

Looks fine, right? Unfortunately, the createContainer() function is called once more immediately after that, resulting in

...
Localization count: 28
//Lots of "finding one from ground db" indicating the page is being localized correctly
finding from ground db
Localization Count: 0
//more "finding one from ground db", this time returning undefined

which as I understand it means, the Ground DB was emptied without me doing it.

Please help me to fix this. Thanks in advance

Slind14 commented 7 years ago

@raix do you have any suggestions on how to resolve this issue or go about debugging it?

raix commented 7 years ago

try removing ground db from the equation and see if you can get things running - then ground the data afterwards.

paranoico commented 7 years ago

Hello @raix, we have inspected your great code and found same behavior using Mantrajs.

As far as we could find, Meteor is removing all data from collections if it is not used (or seems like that).

Then ground DB remove also all local data in this code on function observeSource: 'removed': doc => { if (!this.lastUpdatedAt) { console.log('Removiendo: ', doc); if (this !== source) { this.setDocument(doc, true); } this.saveDocument(doc, true); } }

So, on my side we think there should be some way to detect when collection is cleared and then DO NOT remove documents from local storage (IndexedDB in our case).

¿Do you know if such a thing exists?

Thanks in advance.

raix commented 7 years ago

you could stop the ground db observe when the subscription / data is loaded

raix commented 7 years ago

ref: https://github.com/GroundMeteor/db#usage

paranoico commented 7 years ago

But if we stop observer, the collection will not be in sync with server anymore.

For now, we are testing to use https://github.com/ccorcos/meteor-subs-cache in conjunction with GroundDB II. So collections will not expire and data maintained in Minimongo. Let me see how it works.

paranoico commented 7 years ago

As far as we have tested, I can confirm that it works correctly in our use case (about 30 grounded collections) when using https://github.com/ccorcos/meteor-subs-cache and setting expireAfter to -1.

Then GroundDB does not erase local data (IndexedDB in our case) since collections are not stopped anymore.

aqib1604 commented 6 years ago

@raix Do you have any update on this? When I use Ground DB, My data gets cleared and I am getting empty collections. Although after removing Ground DB, Its working fine. Seems to be issue of an Ground DB.