Skip to content

Updating persistence type with v9 #6067

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

Closed
tiagotwistag opened this issue Mar 14, 2022 · 11 comments · Fixed by #7128
Closed

Updating persistence type with v9 #6067

tiagotwistag opened this issue Mar 14, 2022 · 11 comments · Fixed by #7128

Comments

@tiagotwistag
Copy link

[REQUIRED] Describe your environment

  • Operating System version: macOS Big Sur 11.3.1
  • Browser version: React-native 0.64.3
  • Firebase SDK version: 9.6.5
  • Firebase Product: auth

[REQUIRED] Describe the problem

After upgrading from v8 to v9 I'm no longer able to change the auth persistence type on the go, as of v8 I was able to set a persistence type to none(inMemoryPersistence) and from there to local(browserLocalPersistence) and everything work as expected but since v9 If I go to persistence type none I'm not able to go back to local, I say that because if I set it to none and after to local and close the app the authentication is lost. On the other hand, if I trigger it to only set the persistence type to local everything works as expected, So I believe the issue comes from going to none first.

Steps to reproduce:

  1. Set persistence to none
  2. Login
  3. Update persistence to local
  4. Close & reopen the app

Relevant Code:

V8

Update to none

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE);

Update to local

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL);

V9

Update to none

setPersistence(inMemoryPersistence)

Update to local

setPersistence(browserLocalPersistence)
@sam-gc
Copy link
Contributor

sam-gc commented Mar 14, 2022

Hi @tiagotwistag, I'm unable to reproduce this. If I set it to in memory first, then to local, then refresh and initialize auth, currentUser is properly populated.

Would you mind checking to see if the user is present in local storage after you setPersistence to local? (The key will be firebase:authUser:<your-api-key>). Would you also mind sharing how you're initializing the Auth library? Are you using getAuth() or initializeAuth()?

@tiagotwistag
Copy link
Author

tiagotwistag commented Mar 15, 2022

Hi @sam-gc, thank you for taking the time to get into it, I'm initializing the auth using getAuth.
Related to the localstorage, I'm using the SDK in a different environment(React-native 0.64.3), but I went and verified the async storage and if I don't trigger a from none to local storage I have the data stored there but if for some reason I go to none and then back to local it returns null

@tiagotwistag
Copy link
Author

Hey @sam-gc any update?

@supermisha
Copy link

@sam-gc @jbalidiong any news on this? Thanks folks!!

@tiagotwistag
Copy link
Author

Hey once again @sam-gc is there anything we can do to get this one fixed?

@sam-gc
Copy link
Contributor

sam-gc commented May 9, 2022

Hi @tiagotwistag, my apologies for missing your earlier response. I missed that you were using react native. For v8, LOCAL persistence (it was an enum) simply used the correct react native local persistence internally. In v9, since everything is modular, when you call setPersistence() you're actually passing in a persistence object. React Native doesn't work with localStorage across sessions, if I understand correctly.

In your case, you'll need to call setPersistence() with the response you obtain from getReactNativeLocalPersistence(). If you want to initialize the Auth library with this persistence from the beginning, you'll have to use initializeAuth() with the persistence field defined as discussed in this doc: https://firebase.google.com/docs/auth/web/custom-dependencies.

Please investigate if this fixes the issue and report back :)

@tiagotwistag
Copy link
Author

Hey @sam-gc, thank you once again for the follow up, I just tested it and seems that now going to local is not working, I might be missing something, here is the code I'm using

export const setAuthenticationPersistence = type => {
  return setPersistence(
    auth,
    type === 'none'
      ? inMemoryPersistence
      : getReactNativePersistence(AsyncStorage),
  );
};

This code is later called by a react useEffect

  useEffect(() => {
    if (userIsAuthenticated) {
      setAuthenticationPersistence(hasMissingAuthSteps ? 'none' : 'local');
    }
  }, [userIsAuthenticated, hasMissingAuthSteps]);

Just to give some more context, with the previous code

export const setAuthenticationPersistence = type => {
  return setPersistence(
    auth,
    type === 'none' ? inMemoryPersistence : browserLocalPersistance,
  );
};

going local would work, the issue would be going inMemory first and then jumping to local, that would break the persistence for some reason

@sam-gc
Copy link
Contributor

sam-gc commented May 10, 2022

Thanks for these snippets @tiagotwistag, would you mind trying one more thing? Store the result of getReactNativeLocalPersistence as a singleton and use that object that you create once instead of calling getReactNativeLocalPersistence every time your setAuthenticationPersistence function is called

@tiagotwistag
Copy link
Author

Did some quick tests and doing the follow:

import AsyncStorage from '@react-native-async-storage/async-storage';
import {
  getReactNativePersistence,
  reactNativeLocalPersistence,
} from 'firebase/auth/react-native';

const testPer = getReactNativePersistence(AsyncStorage);

export const setAuthenticationPersistence = type => {
  return setPersistence(auth, type === 'none' ? inMemoryPersistence : testPer);
};

Produces the same results as before, but if I do the follow:

import {
  getReactNativePersistence,
  reactNativeLocalPersistence,
} from 'firebase/auth/react-native';

export const setAuthenticationPersistence = type => {
  return setPersistence(
    auth,
    type === 'none' ? inMemoryPersistence : reactNativeLocalPersistence,
  );
};

Works perfectly fine, going trough the package code my guess is that if I call getAuth it does get initialized with the default reactNativeLocalPersistence and changing it after creates this inconsistency of not using the same storage after updating the persistence, correct?

export const reactNativeLocalPersistence: Persistence =
  getReactNativePersistence({
    getItem(...args) {
      // Called inline to avoid deprecation warnings on startup.
      return ReactNative.AsyncStorage.getItem(...args);
    },
    setItem(...args) {
      // Called inline to avoid deprecation warnings on startup.
      return ReactNative.AsyncStorage.setItem(...args);
    },
    removeItem(...args) {
      // Called inline to avoid deprecation warnings on startup.
      return ReactNative.AsyncStorage.removeItem(...args);
    },
  });

export {getReactNativePersistence};

export function getAuth(app: FirebaseApp = getApp()): Auth {
  const provider = _getProvider(app, 'auth');

  if (provider.isInitialized()) {
    return provider.getImmediate();
  }

  return initializeAuth(app, {
    persistence: reactNativeLocalPersistence
  });
}

@tiagotwistag
Copy link
Author

tiagotwistag commented May 13, 2022

Hey @sam-gc can you just give a quick look to it and see if what I just said makes sense? if so, you can close the ticket, thanks for help 👐

@sam-gc
Copy link
Contributor

sam-gc commented Jun 7, 2022

Hi @tiagotwistag, my apologies for the delayed reply. Yes, the way you described it is correct. You can either use getReactNativePersistence and use initializeAuth, or you can use getAuth with the default reactNativeLocalPersistence. Thanks for digging into it!

@firebase firebase locked and limited conversation to collaborators Aug 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants