[SOLVED] Clarify Meteor.loggingIn sequence (for react-native)

With Meteor 1.8.1, I want to use Meteor.loggingIn && Meteor.user to display the Login Screen or the Connected Screen. But it seems that there is a ghost state in between …
Here is the log sequence:

DEBUG userId, isLoggedIn, loggingIn null false true       ---> OK it's loggingIn
Connected to DDP server.
handleDDPConnected
DEBUG  userId,  isLoggedIn, loggingIn null false true    ---->  OK
DEBUG  userId, isLoggedIn, loggingIn null false false    ----> ??? loggingIn turns to false, before userId is set
(so here is goes to display flash LoginScreen)
DEBUG  userId, isLoggedIn, loggingIn FardSuwok2EAdCes9 true false ---> OK userId is set
User logged in
(so here is goes to display Connected Screen)

How can I get rid of the flash LoginScreen ?

Logged in is simply Boolean(Meteor.user()) (or Meteor.userId()) or !!Meteor.userId() or simply Meteor.user(). You don’t really need the other states.

@paulishca the question is about loggingIn, when one has already been authenticated and is autologged, during this time loggingIn is set to true. I don’t want to display Login Screen if the user was already logged (it’s a mobile app). The problem is that loggingIn in set to false before the user/userId is set a few milliseconds later. If it would set the userId then loggingIn to false, I think it would solve the issue.

Digging into account-base/account_client :

      this._setLoggingIn(false);   // <<<<<< loggingIn is set to false BEFORE
      if (error || !result) {
        error = error || new Error(
          `No result from call to ${options.methodName}`
        );
        loginCallbacks({ error });
        return;
      }
      try {
        options.validateResult(result);
      } catch (e) {
        loginCallbacks({ error: e });
        return;
      }
       // >>>>>>> THEN AFTER here it set's the userId <<<<<<<
      // Make the client logged in. (The user data should already be loaded!)
      this.makeClientLoggedIn(result.id, result.token, result.tokenExpires);            

So loggingIn is set before userId is set :wink:

anyone from core team to confirm this, do I need to open an issue ?

I asked about this last year too – here’s the link:

That seems to work on my app. I don’t encounter flashes of the login screen when not needed. Possibly it has something to do with the front end framework I’m using (React).

Would it be possible to check if userId, isLoggedIn, loggingIn are null false false, and if so skip the login screen until they are all filled in with their final values?

but you need to display login screen to log the first time too when userId, isLoggedIn, loggingIn are null false false :wink:
As I’m using react-native front end, the problem seems to come from the react-native-meteor package which handles loggingIn.
This is fixed and merged in https://github.com/lc3t35/react-native-meteor
Now I have what was expected : loggingIn changes from true to false when userId changes from null to userId value.

DEBUG SwitchNavigator user, isLoggedIn, loggingIn null false true
Connected to DDP server.
handleDDPConnected
DEBUG SwitchNavigator user, isLoggedIn, loggingIn null false true
DEBUG SwitchNavigator user, isLoggedIn, loggingIn FardSuwok2EAdCes9 true false

:+1:

Ok, this could work for react-native too as it does in web.

Switching routes based on the user state could be something like this (without waiting on your server). If your app is able to display some offline content, you don’t need a confirmation from the DDP server. You just want to know if you have a valid user.

In the case below Redirect is coming from react-router-dom.

const iAmRemembered = localStorage.getItem('Meteor.loginTokenExpires') &&
    new Date(localStorage.getItem('Meteor.loginTokenExpires')).getTime() > Date.now()

  if (iAmRemembered && !Session.get('notFirstEntry')) {
    Session.set('notFirstEntry', true) // means I just opened the first page on the website 
    if (window.location.pathname === '/') {
      return <Redirect to='/what_I_want_to_show' />
    }
  }