简体   繁体   中英

Meteor: this.userId and Meteor.userId() both are null within a Meteor Method

To boil down this issue to the basic problem and a minimum of code, I've created a plain new meteor app, added the accounts-password package and added the following code snippet. There's a test user in my database.

Meteor.methods({
    'testMethod': function() {
        console.log('test2:', this.userId); // => null
        console.log('test3:', Meteor.userId()); // => null
    }
});

if (Meteor.isServer) {
    Meteor.publish('testPublication', function() {
        console.log('test1:', this.userId); // => 1c8tHy3zb8vP9E5yb
        Meteor.call('testMethod');
    });
}

if (Meteor.isClient) {
    Meteor.loginWithPassword('test', 'test', function() {
        Meteor.subscribe('testPublication');
    });
}

As you can see, within the publication this.userId contains the correct userId. But within the Meteor Method testMethod both this.userId and Meteor.userId() are returning null .

Is this a meteor bug or is this approach wrong?

This is the expected behavior. It is because you are calling the method from the server. There is no user on the server hence the userId on the method invocation obejct ( this ) is null . Try calling it from the client when you are logged in.

It is because you don't return a response from the server to your client side. This is how you do it:

methodName: function (arg1, arg2){
    //do something with the arguements, maybe throw an error:
    if(!Meteor.user()){
        //it won't do anything after the error so you don't have to write an else statement
        throw new Meteor.Error('You are not a user!');
    }

    return Meteor.userId()
},

and your call in the client side :

Meteor.call('methodName', arg1, arg2, function(err, res){
    if(err){
        //err is the error you throw in the method
        console.log(err)
    } else {
        //result is what you return from your method
        console.log(res)
    }
});

The Meteor.userId() works perfectly in methods or client side, out of the box.

Additionally, publish can only return a cursor to the client side as far as I remember. You can't even return an object you find with findOne() .

EDIT :

You are calling a method from the server publication without passing any arguements. If you call a method from the client side, from a user account, it won't come back as null or even though I believe it is wrong, it might also work if you pass this.userId as an arguement to your current .call() in your publish but it will still not give you Meteor.userId() in the method. It will return you the arguement/id you pass from the publish.

How about this?

function testMethod() {
    console.log('test2:', this.userId); // => should be 1c8tHy3zb8vP9E5yb
}

Meteor.methods({
    'testMethod': testMethod
});

if (Meteor.isServer) {
    Meteor.publish('testPublication', function() {
        console.log('test1:', this.userId); // => 1c8tHy3zb8vP9E5yb
        testMethod.call(this);
    });
}

if (Meteor.isClient) {
    Meteor.loginWithPassword('test', 'test', function() {
        Meteor.subscribe('testPublication');
    });
}

In methods,replace

 console.log('test2:', this.userId); // => null
 console.log('test3:', Meteor.userId()); // => null

With

if(Meteor.user)    //USE THIS!
 {
 console.log('test2:', Meteor.userId()); // => null
 console.log('test3:', Meteor.userId()); // => null

 }

this.userid won't work in methods. However, using Meteor.userId return the id of the user who invoked the method call.

After lots of discussions and some answers, it seems like Meteor Methods are not intended to be called from the server side and the userId is simply not available if not called from the client side. Despite this is not helpful at all and a counter intuitive behavior of the framework, it's the way Meteor works.

However there's a package called meteor-user-extra ( https://github.com/peerlibrary/meteor-user-extra ) which makes Meteor.userId() work also inside the publish endpoint functions and solved my problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM