Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meteor.js Publishing and Subscribing?

Okay, so I am a bit confused about something with Meteor.js. I created a site with it to test the various concepts, and it worked fine. Once I removed "insecure" and "autopublish", I get multiple "access denied" errors when trying to retrieve and push to the server. I belive it has something to do with the following snippet:

Template.posts.posts = function () {
    return Posts.find({}, {sort: {time: -1}});
}

I think that it is trying to access the collection directly, which it was allowed to do with "insecure" and "autopublish" enabled, but once they were disabled it was given access denied. Another piece I think is problematic:

else {
    Posts.insert({
    user: Meteor.user().profile.name,
    post: post.value,
    time: Date.now(),
});

I think that the same sort of thing is happening: it is trying to access the collection directly, which it is not allowed to do.

My question is, how do I re-factor it so that I do not need "insecure" and "autopublish" enabled?

Thanks.

EDIT

Final:

/** 
* Models
*/
Posts = new Meteor.Collection('posts');

posts = Posts

if (Meteor.isClient) {

    Meteor.subscribe('posts');


}

if (Meteor.isServer) {

    Meteor.publish('posts', function() {
        return posts.find({}, {time:-1, limit: 100});
   });


    posts.allow({

        insert: function (document) {
            return true;
        },
        update: function () {
            return false;
        },
        remove: function () {
            return false;
        }

    });

}
like image 785
Aristides Avatar asked Sep 22 '13 18:09

Aristides


1 Answers

Ok, so there are two parts to this question:

Autopublish

To publish databases in meteor, you need to have code on both the server-side, and client-side of the project. Assuming you have instantiated the collection (Posts = new Meteor.Collection('posts')), then you need

if (Meteor.isServer) {
    Meteor.publish('posts', function(subsargs) {
        //subsargs are args passed in the next section
        return posts.find()
        //or 
        return posts.find({}, {time:-1, limit: 5}) //etc
   })
}

Then for the client

if (Meteor.isClient) {
    Meteor.subscribe('posts', subsargs) //here is where you can pass arguments
}

Insecure

The purpose of insecure is to allow the client to indiscriminately add, modify, and remove any database entries it wants. However, most of the time you don't want that. Once you remove insecure, you need to set up rules on the server detailing who can do what. These two functions are db.allow and db.deny. E.g.

if (Meteor.isServer) {
    posts.allow({ 
        insert:function(userId, document) {
            if (userId === "ABCDEFGHIJKLMNOP") {  //e.g check if admin
                return true;
            }
            return false;
        },
        update: function(userId,doc,fieldNames,modifier) {
            if (fieldNames.length === 1 && fieldNames[0] === "post") { //they are only updating the post
                return true;
            }
            return false;
        },
        remove: function(userId, doc) {
            if (doc.user === userId) {  //if the creator is trying to remove it
                return true;
            }
            return false;
        }
    });
}

Likewise, db.deny will behave the exact same way, except a response of true will mean "do not allow this action"

Hope this answers all your questions

like image 195
Zwade Avatar answered Sep 29 '22 17:09

Zwade