Can we remove publications?

Are we able to remove publications?

Not after the app has started. Why would you need to?

@sashko Suppose we have a site with special promotions that should only be visible on Fridays, so at the beginning of the day Friday set publications, then at the end of the day Friday remove publications, so even if clients subscribe naively to subscriptions they won’t get any data except on Fridays.

I believe I can currently do something like this:

import isFriday from './utilities/time'
import Promos from './collections/Promos'

Meteor.publish('fridayPromotions', function() {
    if (isFriday())
        return Promos.find()
    else
        return []
})

What if a client leaves a browser tab open at 11:30pm on Friday, then 12:00am Saturday rolls around (it is already tricky enough to keep track of time zones, but suppose we got past that already).

Will the subscription remain open since it was subscribed to on Friday? How might be stop it when Saturday rolls around?

I was thinking something like

let pub = Meteor.publish('...', function() {...})

// somewhere else, when Friday rolls around:
pub.stop() // Sends a request to connected clients to close the subscription.

Hmm, I see. There are a couple related issues:

  1. Should it be friday on the server, or the client?
  2. Does the client knowing about the promotions matter? i.e. could you just not show them in the UI, even though you are subscribed?
  3. Could you just unsubscribe from the client?

I think what I would do is not treat this as a security issue where we absolutely must not publish this data; instead I’d let the client decide if it wants to load friday promotions, and have logic in the UI to just not display them. Then if the client wants to take advantage of a promotion, do the security check then, so that even if the client figures out how to find the promotion, it can’t take advantage of it.

I do agree that it would be good to be able to invalidate a specific publication.

There’s also a community package that makes publications reactive:

They have a code sample that looks similar to what you are trying to do: https://github.com/peerlibrary/meteor-reactive-publish#examples

2 Likes

Ah, that’s cool! The reactive publish makes this a lot easier. I’d just make isFriday() a reactive data source in my case. :smile:

Using a reactive date source is a good idea. If you looking for some other way. You can do like this as well.
See:

const subStore = {};
let id = 0;

Meteor.publish('fridayPromotions', function() {
  if(!Friday()) {
    throw new Error('Cheater');
  }
  // do the stuff
  const myId = id++;
  subStore[myId] = this; 
  this.onStop(() => {
    delete subStore[myId];
  });
});

onFriday(() => {
  _.each(subStore, (sub) => {
    sub.stop();
  });
  subStore = {};
});
2 Likes

Thanks @arunoda, good idea! That’s an interesting way to store the server-end of the subs for later reference, even once the function has returned. That’s exactly the non-reactive solution.

1 Like