Subscribe to collection which has been published during Accounts.onLogin


#1

I couldn’t subscribe to collection which has been published during login. For example consider the below code

Collections.js

if(Meteor.isServer){
  Accounts.onLogin(function(user){
     TempDB = new Mongo.Collection("tempdb");
     Meteor.publish('tempinfo', function() {
        return TempDB.find();
    });
 });
}

MainLayout.js

Template.MainLayout.onCreated(function(){
   TempDB = new Mongo.Collection("tempdb");
   Meteor.subscribe('tempinfo');
   console.log(TempDB.find({},{limit:1}).fetch());
   //The above console.log prints an empty array 
});

As shown above the MainLayout couldn’t able to subscribe to the published data. Please help on this one. Thanks in advance.

[Note: No matter what, I need to publish the collection on Login only. For the simplicity I’ve mentioned the above simple example]


#2

Meteor.publish doesn’t publish when you run it. What it does is register a publication function that will run later when the server gets a subscribe call. In your code you are registering the method every time a user logs in and you really don’t want this to be the case. Instead you should run this code once and not execute sensitive publication code if the user isn’t logged in.

On The Server…

Meteor.publish('tempinfo', function(){
    if(!this.userId){
        return this.ready();
    }
    //run authenticated publication code here
});

#3

@copleykj

Thank you very much. I understand how it works correctly now. But it doesn’t solve my problem. Tracker.autorun helped to solve the problem, which obviously similar to what you have told.

Template.MainLayout.onCreated(function(){
   TempDB = new Mongo.Collection("tempdb");
   Tracker.autorun(function () {
      if (Meteor.userId()) {
         Meteor.subscribe('tempinfo');
         console.log(TempDB.find({},{limit:1}).fetch());
         //Prints the array document
      }
   });
});

But it only partially solved my problem. I am getting an exception in Server - Ignoring duplicate publish named tempinfo. Do you have any idea how to solve that?


#5

If you still have your Meteor.publish inside of Accounts.onLogin they you will get this because you are trying to register a delicately named publication. You have to move this code so that it stands on it’s own and only runs once.

As far as the autorun goes, if you just need the data available whenever the user is logged in and you don’t need to run any other code, then my recommendation is a null publication with auth check.

Meteor.publish(null, function() {
    if(this.userId){
        return this.ready();
    }
    //publish code here
}, {is_auto:true})

This publication will be re-run any time the user connects or disconnects and will provide the same functionality that the subscribe in the autorun does, only in a much cleaner way. As another bonus, if you are using fast-render, null publications are run and data sent down to the client with the initial payload so they are available on page load.