看起来,如果用户登录到Meteor应用程序,然后丢失并重新获得其DDP连接,则会有一个短暂的时刻,客户端认为它在服务器之前已登录 .
例如,我有一个容器组件,根据 Meteor.loggingIn()
的结果进行更新:
const MainNavigationContainer = createContainer(props => {
return {
meteorReady: Meteor.loggingIn() === false
}
}, MainNavigation);
在 MainNavigation
组件中,我运行一个Meteor方法,该方法应根据用户的 _id
返回结果(我试图删除不相关的代码):
class MainNavigation extends Component {
componentWillReceiveProps(nextProps) {
this.setInitialRoute(nextProps);
}
setInitialRoute = (props) => {
// Set up initial route
if (props.meteorReady) {
if (!Meteor.user()) {
this.setState({initialRoute: routes[1]});
} else {
Meteor.call('/user/events/isActive', (e, eventId) => {
if (eventId) {
// Do some stuff
} else {
// Do some other stuff
}
});
}
}
};
render() {
return (
this.props.meteorReady && this.state.initialRoute ?
<Navigator
ref={navigator => this.navigator = navigator}
initialRoute={this.state.initialRoute}
renderScene={(route, navigator) => { ... }}
/> : (
<View style={styles.container}>
<ActivityIndicator animating={true}/>
</View>
)
)
}
}
只有在定义 Meteor.user()
时才应运行 /user/events/isActive
方法调用(这应该意味着用户已登录) . 但是,当我查看服务器调用时:
Meteor.methods({
'/user/events/isActive': function () {
console.log('userId:', this.userId);
if (this.userId) {
const member = Members.findOne({userId: this.userId});
if (member) {
return member.eventId;
}
return false;
}
return false;
}
});
此方法的第一次调用(在DDP断开连接并重新连接之后)最终 this.userId
等于 null
.
基本上,如果在客户端上定义 Meteor.user()
,我希望在服务器上定义 this.userId
. 但是,似乎客户端上的minimongo在实际登录之前会给出误报(当他们断开连接并重新连接时) .
我的问题是:如果在客户端上定义 Meteor.user()
,我可以安全地假设将在服务器上定义 this.userId
吗?截至目前,我会说我不能,所以有没有其他方法让我可靠地确定用户是否真的从客户端登录?
1 回答
经过大量的调试,我终于弄清楚发生了什么 .
只要反应计算失效,
container
就会向其子组件发送新的道具 . 此外,Meteor方法是异步的,如果它们未在服务器上解析,客户端将继续尝试获得响应,直到重新连接 . 但是,传递到setInitialRoute
的props
是来自componentWillReceiveProps
的nextProps
.因此,正在发生的事情是,当流星服务器断开连接时正在进行呼叫,并且在重新连接之后发生了该呼叫的解决方案 . 所以之前对流星方法的调用正在评估中,给我一个
null
的this.userId
.为了解决这个问题,我只需要在meteor方法的回调中添加一个条件,以确保在用户实际登录时进行评估(使用当前的props而不是传入
nextProps
):这可以防止在客户端上评估该方法调用的结果,并解决了我的问题 .