22

Firebase auth does not persist logged in user and everytime I refresh or reopen app I have to sign in again.

I have tried setting persistence to local and the callback does verify its set but the persistence is still no working

For setting persistence I am using...

  //set auth persistence
  firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
    .then(function() {
      console.log("successfully set the persistence");

    })
    .catch(function(error){
    console.log("failed to ser persistence: " + error.message)
  });

. . . For signing in I am using this code

firebase.auth().signInWithEmailAndPassword(email, password)
      .then((user) =>{
        this.checkAccountStatus(user.uid, user.email);
      })
      .catch(function(error) {
      // Handle Errors here.

      var errorCode = error.code;
      var errorMessage = error.message;

      console.log(errorMessage)
      // ...
    });

And here is the code I am using to check login status...

if (firebase.auth().currentUser) {
        const currentUser = firebase.auth().currentUser;
        console.log("Signed in username" + currentUser.displayName);

        this.props.navigation.navigate('AppTab');
      }else{
        console.log("no user signed in");
        this.props.navigation.navigate('AuthTab');
      }

if there anything I am not doing right

benomatis
  • 5,536
  • 7
  • 36
  • 59
Nouman Tahir
  • 819
  • 1
  • 9
  • 26

3 Answers3

24

You don't need to set persistence. Firebase handles it for you by default. You just need to call this function to check whether user is logged or not:

firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        console.log('user is logged');
      }
});

This will not be triggered only if user has sign out or cleaned app data.

You can find more details in the official docs: https://firebase.google.com/docs/auth/web/manage-users

Hope it helps.

Eric Citaire
  • 4,355
  • 1
  • 29
  • 49
soutot
  • 3,531
  • 1
  • 18
  • 22
  • 2
    I am using this method instead... firebase.auth().currentUser;...it doesnt work once the app refreshed using Cmd+R or restarted from simulator itself – Nouman Tahir Sep 10 '17 at 18:55
  • You should replace your method to the one I provided. By the docs, that it the correct way to check whether a user is logged or not after the app has been closed. Let me know if worked. – soutot Sep 10 '17 at 19:07
  • 1
    just tried it out, it didnt work and I wasnt expecting it to either, because according to docs, if user is already signed is .currentUser() is the right way to know whether status is signed in or out....see heading "Get the currently signed-in user" at https://firebase.google.com/docs/auth/web/manage-users – Nouman Tahir Sep 11 '17 at 05:23
  • I always used the code I provided in my componentWillMount on my login screen and never had problems. Even if user closes the app, when he opens again it checks if it's a logged user and navigate it to the home screen. Would you mind sharing where did you add it? – soutot Sep 11 '17 at 15:23
  • 1
    @soutot's answer is correct. LOCAL persistence is the default in react native and you should use `onAuthStateChanged` to detect that initially. – bojeil Sep 12 '17 at 01:05
  • it is in component did mount...and I did try onAuthStateChanged as well...in any case I have to relogin.. componentDidMount() { if (firebase.auth().currentUser) { const currentUser = firebase.auth().currentUser; console.log("Signed in username" + currentUser.displayName); this.props.navigation.navigate('AppTab'); }else{ console.log("no user signed in"); this.props.navigation.navigate('AuthTab'); } } – Nouman Tahir Sep 12 '17 at 12:09
  • is it possible that its being caused because of iOS simulator...? – Nouman Tahir Sep 13 '17 at 18:23
  • I don't think so. I always used it and never had problems on simulators or real devices. Are you importing `firebase` or `react-native-firebase` in your project? Maybe this can be the truly issue. I know it works with `firebase` module. – soutot Sep 13 '17 at 18:38
  • I am working with 'firebase' and not 'react-native-firebase' ... wanna stay as native as possible.... can you tell me you firebase and react-native package versions...might help – Nouman Tahir Sep 15 '17 at 15:04
  • 1
    The current project I'm working uses Firebase 4.1.3 and RN 0.42.3 – soutot Sep 15 '17 at 15:08
  • 2
    @soutot's answer is a better way to do. Here's official doc says: Note: currentUser might also be null because the auth object has not finished initializing. If you use an observer to keep track of the user's sign-in status, you don't need to handle this case. https://firebase.google.com/docs/auth/web/manage-users – Nay Feb 19 '18 at 15:54
  • 1
    This is because the object expires after an hour.. hence why the `auth().currentUser`.. apparently the tokenID is suppose to refresh automatically every hour.. but for React Native apps.. this isn't going to happen of the user has the app closed for that hour... – 9_Dave_9 Mar 16 '20 at 00:44
  • @soutot could you please explain how this will prevent Firebase from signOut after the user reloads the page? I don't really understand where do i have to put the `onAuthStateChanged()` call or why does even Firebase logouts the user after he reloads the page. Thank you! – Dacaramo Mar 28 '22 at 23:41
  • 1
    Hi, just want to note that as of spring, 2023, in react native, firebase auth persistence doesn't work out of the box as described here unless you explicitly set up AsyncStorage as per this answer: https://stackoverflow.com/a/76351899 -- I think this is because AsyncStorage is no longer a default part of RN. – eeeeaaii Jun 26 '23 at 21:47
4

Make sure you do not restrict the 'Token Service API' in the console, with the API key you are using. I did not add the service to my key, and it logged me out every 3-4 hours, even with the right code suggested above.

2

Firebase now recommends to use firestore instead of realtime-database and it manages offline persistence by default. It is clear in its documentation here

You just need to access the user through this code:

if (auth().currentUser !== null) {
      console.log('User is logged in');
      console.log(auth().currentUser.email);
      props.navigation.navigate('Home');
    } else {
      props.navigation.navigate('Login');
}

This code will prop you to home screen if user is logged-in, even when you close the app. To clear the user's credentials, you manually need to sign-out the user using this code.

try {
      auth()
        .signOut()
        .then(props.navigation.navigate('Login'));
    } catch (error) {
      Alert.alert('Error', error.toString());
}

You can also check this simple app (used react hooks in it) for further assistance.

Aun Abbas
  • 540
  • 7
  • 18