正确使用 Meteor.userId()
Posted
技术标签:
【中文标题】正确使用 Meteor.userId()【英文标题】:correct use of Meteor.userId() 【发布时间】:2017-04-22 21:19:22 【问题描述】:这个 Meteor 服务器代码尝试在公共方法“sendEmail”中使用 Meteor.userId(),但有时我会收到错误
Error Meteor.userId 只能在方法调用中调用。使用 this.userId
lib = (function ()
return Object.freeze(
'sendEmail': function(msg)
let userId = Meteor.userId();
//do stuff for this user
,
'otherPublicMethod': function()
//do other things then use sendEmail
lib.sendEmail(); // <---- Error Meteor.userId can only be invoked in method calls. Use this.userId
);
());
// Now I call sendEmail from any where, or can I?
Meteor.methods(
'sendEmail': (msg) =>
lib.sendEmail(msg); // <---- NO error when this is called
,
);
如何解决?谢谢
【问题讨论】:
userId()
不允许在Publications
内使用,但在Methods
内使用没有限制。
【参考方案1】:
我将温和地建议您替换您对IIFE 的使用。相反,您可以利用ES16 modules 来定义您的常用函数。
正如您所指出的,Meteor.userId() 在方法调用中可用,但在服务器上的独立函数中不可用。从方法调用中调用此类函数时,我使用的模式是传入 userId(或实际用户)。例如
imports/api/email/server/utils/emailUtils.js:
const SendEmail = function(userId, msg)
// do stuff
;
export SendEmail;
imports/api/email/server/emailMethods.js:
import SendEmail from '/imports/api/email/server/utils/emailUtils';
Meteor.methods(
'sendEmail': (msg) =>
check(msg, String);
// other security checks, like user authorization for sending email
SendEmail(Meteor.userId(), msg);
,
);
现在,您有一个可重复使用的 SendEmail 函数,您可以从任何方法调用或发布。此外,通过遵循这种模式,您离创建可测试代码又近了一步。即,测试注入 userId 的函数比模拟“this.userId”或“Meteor.userId()”更容易。
【讨论】:
我喜欢 IIFE 而不是模块的一个原因是我可以调用像 funcName.methName 这样的公共方法,并且知道我在调用哪个方法,即需要编写的 cmets 更少。【参考方案2】:如果从任何异步方法调用 lib.sendEmail,请确保绑定 Meteor 环境 例如检查下面模拟异步行为的代码
lib = (function ()
return Object.freeze(
'sendEmail': function (msg)
let userId = Meteor.userId();
console.log(userId);
//do stuff for this user
,
'otherPublicMethod': function ()
//do other things then use sendEmail
lib.sendEmail(); // <---- Error Meteor.userId can only be invoked in method calls. Use this.userId
);
());
// Now I call sendEmail from any where, or can I?
Meteor.methods(
'sendEmail': (msg) =>
//simulate async behaviour + bind environment
Meteor.setTimeout(Meteor.bindEnvironment(function ()
lib.sendEmail(msg); // <---- NO error when this is called
));
//output :
// null - if user has not logged in else
// actual userId - if user is loggedin
//simulate async behaviour without binding environment
Meteor.setTimeout(function ()
lib.sendEmail(msg); // <---- error when this is called
);
//output :
// Exception in setTimeout callback: Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.
,
);
【讨论】:
以上是关于正确使用 Meteor.userId()的主要内容,如果未能解决你的问题,请参考以下文章
userId vs Meteor.userId vs Meteor.userId()
为啥 Meteor.user 和 Meteor.userId 不同?