Friday 19 May 2017

Meteor minimongo shows user logged in on client before server

It appears that if a user is logged in to a Meteor application, then loses and regains their DDP connection, there is a short moment where the client believes that it is logged in before the server does.

For example, I have a container component that updates according to the result of Meteor.loggingIn():

const MainNavigationContainer = createContainer(props => {
    return {
        meteorReady: Meteor.loggingIn() === false
    }
}, MainNavigation);

In the MainNavigation component, I run a Meteor method which should return a result based on the user's _id (I have tried to remove irrelevant code):

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) {
                        let routeData = routes[0];
                        routeData.eventId = eventId;
                        this.setState({initialRoute: routeData});
                    } else {
                        this.setState({initialRoute: routes[3]});
                    }
                });
            }
        }
    };
    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>
            )
        )
    }
}

The /user/events/isActive method call should only be run if Meteor.user() is defined (which should mean the user is logged in). However, when I look at the server call:

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;
    }
});

The first call of this method (after a DDP disconnect and reconnect) ends up with this.userId being equal to null.

Basically, if Meteor.user() is defined on the client, I expect this.userId to be defined on the server. However, it appears that the minimongo on the client is giving a false positive before they are actually logged in (when they disconnect and reconnect).

My question is: If Meteor.user() is defined on the client, can I safely assume that this.userId will be defined on the server? As of now, I would say I cannot, so is there any other way for me to reliably determine if the user is truly logged in from the client side?



via Conor Strejcek

No comments:

Post a Comment