numtel / meteor-mysql

Reactive MySQL for Meteor
MIT License
343 stars 41 forks source link

Subscriptions not updating after logout #33

Open tvogels opened 9 years ago

tvogels commented 9 years ago

When a publication requires a user to be logged in, like this:

Meteor.publish('pubname', function(param) {
  if (!this.userId) {
    this.stop();
    return;
  }
  check(param,Number);
  return liveDb.select(
    'SELECT * FROM table WHERE param = '+liveDb.db.escape(param),
    [ { table: 'table' } ]
  );
});

and there is a subscription like this:

mysubscription = new MysqlSubscription('pubname',null);

(I change the parameter with mysubscription.change() now and then),

then there is a problem with logging out. The desired behaviour is that all current subscriptions automatically clear after calling Meteor.logout(), but this does not happen. Something does change however. Before logging out, mysubscription.ready() returns true, but after it returns false.

Edit: The same behaviour occurs when logging in, actually.

tvogels commented 9 years ago

It turns out it helps to write

    return liveDb.select(
      'SELECT * FROM event WHERE 1=2',
      [ { table: '---' } ]
    );

instead of

this.stop();
return;

Is there a more elegant solution for returning an 'empty collection'?

numtel commented 9 years ago

Hmm this is an interesting case. There is no built-in way to deal with this but your suggestion of returning an empty collection points me to this solution:

Meteor.publish('pubname', function(param) {
  if (!this.userId) {
    this._session.send({
      msg: 'added',
      collection: this._name,
      id: this._subscriptionId,
      fields: { diff: { removed: null, moved: null, copied: null, added: null } }
    });
    return;
  }
  check(param,Number);
  return liveDb.select(
    'SELECT * FROM table WHERE param = '+liveDb.db.escape(param),
    [ { table: 'table' } ]
  );
});

Send the DDP message to the client directly without instantiating another LiveMysqlSelect instance. The change() method will automatically clear the results before processing the next diff so in this case, just send a null diff DDP message and the result will be an empty collection.

Hopefully that helps :smile_cat: