Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication not consistently persisting between sessions #980

Closed
willbattel opened this issue Apr 13, 2018 · 18 comments
Closed

Authentication not consistently persisting between sessions #980

willbattel opened this issue Apr 13, 2018 · 18 comments
Labels
help: general General help wanted help: needs-triage Issue needs additional investigation/triaging. platform: ios plugin: authentication Firebase Authentication Workflow: Waiting for User Response Blocked waiting for user response.

Comments

@willbattel
Copy link

willbattel commented Apr 13, 2018

Issue

Some of our users (about 20% at this point) are losing their authentication between sessions. This includes terminating the app, or simply leaving it in the background for a while. The effected users have to re-login every session. For those 20% it is happening very frequently.

We offer both Facebook and Phone authentication. The problem is not discriminating between providers- both are experiencing this.

This is the onAuthStateChanged subscription code in our root component.

componentDidMount() {
    this.unsubscribeFromAuth = Firebase.auth().onAuthStateChanged((user) => {
        if (user && user.uid) {
            Firebase.auth().currentUser.getIdToken(true).then((token) => {
                if (!token) {
                    Helpers.logout(false);
                }
                else {
                    // init rest of app, send user to primary navigation component, etc...
                }
            })
            .catch(() => {
                Helpers.logout(false);
            });
        }
        else
            // send user to login screen
    });
}

componentWillUnmount() {
    if (this.unsubscribeFromAuth) {
        this.unsubscribeFromAuth();
        this.unsubscribeFromAuth = null;
    }
}

This is the logout method. If the parameter passed is false, an error message appears. The users getting logged out are not getting the error message. We have confirmed that the error message is functioning properly for other cases. This means that the logout() function isn't being called.

logout(intentional) {

    const logoutMessage = (intentional) ? 'You have been logged out.' : 'Sorry! Something went wrong and you were signed out.';
    // show logoutMessage

    Firebase.auth().signOut().then(() => {
        console.log('signed out');
        LoginManager.logOut();
        Firebase.analytics().logEvent('logout', { error: (intentional) ? 0 : 1 });
        return Storage.delete('credential');
    })
    .then(() => {
        console.log('deleted credential');
        // go to login screen
    })
    .catch((error) => {
        Log.error(error);
        // go to login screen
    });
}

It is possible that this is related to #962. There seems to be a correlation between the users affected by both issues, but it is not a 100% match by any means.

Environment

  1. Application Target Platform: iOS (we target both but do not have enough Android users to know if it is affecting Android)
  1. Development Operating System: macOS High Sierra
  1. Build Tools: Xcode 9.2, iOS 10.0 through 11.3
  1. React Native version: 0.54.4
  1. RNFirebase Version: 3.3.1
  1. Firebase Module: Authentication

Any ideas? Thanks!

@willbattel
Copy link
Author

Actually, this seems to be affecting closer to 40% of our users, who have to re-login every time. This is a very UX-breaking issue that we're not sure how to deal with.

@Ehesp Ehesp added the plugin: authentication Firebase Authentication label Apr 17, 2018
@Salakar Salakar added platform: ios help: needs-triage Issue needs additional investigation/triaging. help: general General help wanted labels Apr 18, 2018
@chrisbianca
Copy link
Contributor

Can I ask why you're doing this part?

Firebase.auth().currentUser.getIdToken(true).then((token) => { ... }

When you say an error appears - how are you presenting this to your user?
I assume you have checked the error property in analytics to clarify that your assumption is correct?

Beyond that, I'm really not to sure what to suggest - ultimately onAuthStateChanged is a wrapper around the underlying functionality from the native SDK, although we do do some caching in the JS side.

Having a look at the code, there is currently the tiniest point of time where the user might incorrectly be reported as null: https://github.com/invertase/react-native-firebase/blob/master/lib/modules/auth/index.js#L106

You'll notice that we set _authResult to true, before creating the User. If, in that instant, a new subscription to onAuthStateChanged was created then it would send null, rather than the User object (https://github.com/invertase/react-native-firebase/blob/master/lib/modules/auth/index.js#L137) which would be incorrect. This should be a tiny fraction of time, but I guess it's possible - I'm just surprised that it would lead to so many people being affected...

I can certainly fix this, or you could manually change the file in your build to move the user creation before the setting of the _authResult and do another release to see whether this makes any difference?

I'm assuming you haven't been able to reproduce locally at all?

@chrisbianca chrisbianca added the Workflow: Waiting for User Response Blocked waiting for user response. label Apr 25, 2018
@willbattel
Copy link
Author

willbattel commented Apr 25, 2018

Can I ask why you're doing this part?

We call Firebase.auth().currentUser.getIdToken(true).then((token) => { ... } because after the user is logged in we immediately need the token to attach to our location service HTTP POST URL so that its requests are authenticated.

When you say an error appears - how are you presenting this to your user?

If there is ever an explicit error with authentication, we log the user out, send them to the login screen, and display an error message. This mostly applies to edge cases where the authentication may expire or be otherwise invalidated mid-session. However, in this case the user is sent to the login screen without any error message after having authenticated in a recent session.

When the app boots, we subscribe to onAuthStateChanged and then wait for the callback. If the callback indicates they are authenticated, then they get sent into the app. If they're not authenticated, they start on the login screen. The latter is happening for these users. They get no error message, they just get sent to the login screen. This suggests that the user parameter could be coming back as undefined.

I assume you have checked the error property in analytics to clarify that your assumption is correct?

When this happens, the logout function is not called, therefore we receive no analytics data from the logout event.

I'm assuming you haven't been able to reproduce locally at all?

I have not been able to reproduce this myself yet. I'm only going off of reports from our users. It seems to consistently affect a select number of users. In other words, only X% of devices/users are affected, rather than X% of sessions.

@chrisbianca
Copy link
Contributor

I'll have a chat with @Salakar and talk through this change to confirm it won't affect anything else then try and get a release out.

Is there any pattern to the type of devices that are experiencing this issue? Are they newer, faster devices? Or older, slower devices? Or is it just random? Seems odd that it's the same users/devices that are seeing the issue rather than just a percentage of sessions unless there is some correlation in the performance of the devices...

@chrisbianca
Copy link
Contributor

I've just published v4.0.6 which has this possible fix in - it would be great if you're able to roll this out and see whether it addresses your issues?

@willbattel
Copy link
Author

Sounds good. We're shipping a new version in the next 36 hours, we'll update to 4.0.6 and see what happens.

@chrisbianca
Copy link
Contributor

Perfect, let us know.

@chrisbianca
Copy link
Contributor

@wbattel4607 Have you had a chance to get this released and tested?

@willbattel
Copy link
Author

We've released it and are monitoring for any changes in behavior. I'll let you know what we find.

@chrisbianca
Copy link
Contributor

Perfect, thanks. Fingers crossed!

@chrisbianca
Copy link
Contributor

@wbattel4607 How's this looking?

@willbattel
Copy link
Author

We've been getting fewer reports, although I am hesitant to say it's resolved yet. If you would like to close the issue, go ahead. If we should discover the problem persists we can create a new issue and reference this one.

@chrisbianca
Copy link
Contributor

Will do, thanks.

@Vindexus
Copy link

@chrisbianca can I ask what was the issue here? I'm encountering a similar issue with Firebase Auth in an Angular project and am having trouble narrowing it down.

@delavago
Copy link

delavago commented May 2, 2020

currently have the same issue in my application. i use firestore listeners to stream data into the application but after being left in the background for lets say 2 hours or more and going back to the application the app no longer recieves data from firestore. User has to log out and login back with firebase auth to get it working again. which indicates to me that its an auth issue

@ankitbishtapollo
Copy link

Any updates on this?

@mikehardy
Copy link
Collaborator

@ankitbishtapollo this issue was opened in 2018, and closed in 2018. Why would there be any updates on a 2 year stale issue? If you have problems with current stable versions please open a new issue and respect the template, then people can try to help

@ankitbishtapollo
Copy link

Ok @mikehardy will raise a new ticket. You can close this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help: general General help wanted help: needs-triage Issue needs additional investigation/triaging. platform: ios plugin: authentication Firebase Authentication Workflow: Waiting for User Response Blocked waiting for user response.
Projects
None yet
Development

No branches or pull requests

8 participants