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

Flutter Web Firebase Auth User Logged Out On Page Refresh #9117

Closed
nitroplr opened this issue Jul 16, 2022 · 11 comments · Fixed by #9138
Closed

Flutter Web Firebase Auth User Logged Out On Page Refresh #9117

nitroplr opened this issue Jul 16, 2022 · 11 comments · Fixed by #9138
Labels
resolution: duplicate This issue or pull request already exists

Comments

@nitroplr
Copy link

nitroplr commented Jul 16, 2022

I have a project that is about a year and a half old and after some issues with Firebase I changed how I connect to Firebase by using dart pub global activate flutterfire_cli and flutterfire configure. I now initialize the app using
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
The app works fine except for one thing, now after a year and a half of having the login screen bypassed using the default persistence.LOCAL...every time I go to my site I have to re log in and even on page refresh I have to re log in. However, when using the Chrome debugger I do not have to log in after using hot reload. Any help would be very much appreciated as I am completely stumped. Below is my main.dart where I get my landing page as well as relevant log in code.


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  try {
    FirebaseFirestore.instance.settings = Settings(persistenceEnabled: false);
  } catch (e) {}
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late final Stream<User?> userState;

  @override
  void initState() {
    userState = FirebaseAuth.instance.authStateChanges();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    //theme data for uniformity, see https://flutter.dev/docs/cookbook/design/themes
    //for use, this will make it very easy to change all colors and fonts at once
    return MaterialHelper(materialHome: _getLandingPage(userState));
  }
}

Widget _getLandingPage(Stream<User?> userState) {
  return StreamBuilder<User?>(
    stream: userState,
    builder: (BuildContext context, snapshot) {
      if (snapshot.hasData) {
        if (snapshot.data!.providerData.length == 1) {
          // logged in using email and password
          return snapshot.data!.emailVerified ? GuildsWidget() : LogIn();
        } else {
          // logged in using other providers
          return GuildsWidget();
        }
      } else {
        return LogIn();
      }
    },
  );
}

------------------Log In---------------------


try {
        String trimmedEmail = email.trim();
        //try to sign in
        UserCredential? userCred =
        await FirebaseAuth.instance.signInWithEmailAndPassword(email: trimmedEmail, password: password);
        if (userCred.user!.emailVerified) {
          Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => GuildsWidget()),
                  (Route<dynamic> route) => false);
        }
      } on FirebaseAuthException catch (e) {
        log(e.toString());
        if (e.code == 'invalid-email') {
          showSnackBar(
              context: context, message: 'Email address is invalid, ${5 - signInAttempts} attempts left');
        }
        if (e.code == 'user-not-found') {
          showSnackBar(context: context, message: 'Please Register, ${5 - signInAttempts} attempts left');
        } else if (e.code == 'wrong-password') {
          showSnackBar(context: context, message: 'Invalid Password, ${5 - signInAttempts} attempts left');
        }
      } catch (e) {
        log(e.toString());
      }

@nitroplr
Copy link
Author

Flutter doctor -v
[√] Flutter (Channel stable, 3.0.5, on Microsoft Windows [Version 10.0.19044.1826], locale en-US)
• Flutter version 3.0.5 at C:\Users\nitro\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision f1875d570e (3 days ago), 2022-07-13 11:24:16 -0700
• Engine revision e85ea0e79c
• Dart version 2.17.6
• DevTools version 2.12.2

[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0-rc3)
• Android SDK at C:\Users\nitro\AppData\Local\Android\Sdk
• Platform android-31, build-tools 31.0.0-rc3
• ANDROID_HOME = C:\Users\nitro\AppData\Local\Android\Sdk
• Java binary at: C:\Users\nitro\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\212.5712.43.2112.8512546\jre\bin\java
• Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)
• All Android licenses accepted.

[√] Chrome - develop for the web
• Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[!] Visual Studio - develop for Windows (Visual Studio Build Tools 2017 15.9.36)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools
• Visual Studio Build Tools 2017 version 15.9.28307.1525
• Windows 10 SDK version 10.0.17763.0
X Visual Studio 2019 or later is required.
Download at https://visualstudio.microsoft.com/downloads/.
Please install the "Desktop development with C++" workload, including all of its default components

[√] Android Studio (version 2021.2)
• Android Studio at C:\Users\nitro\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\212.5712.43.2112.8512546
• Flutter plugin version 66.0.1
• Dart plugin version 211.7817
• Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

[√] IntelliJ IDEA Ultimate Edition (version 2022.1)
• IntelliJ at C:\Users\nitro\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\221.5921.22
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin version 221.5787.37

[√] Connected device (4 available)
• sdk gphone x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19044.1826]
• Chrome (web) • chrome • web-javascript • Google Chrome 103.0.5060.114
• Edge (web) • edge • web-javascript • Microsoft Edge 102.0.1245.44

[√] HTTP Host Availability
• All required HTTP hosts are available

@anchann
Copy link

anchann commented Jul 16, 2022

I've also been pulling my hair out for three hours now. There's a bunch of discussion of various closely related bugs in previous versions of various libraries, but nothing I've tried os far works. The closest issue I found is this one:

#5372

but it still doesn't help. My setup:

  • firebase_auth 3.4.2
  • using StreamBuilder with FirebaseAuth.instance.authStateChanges() as the stream (as opposed to all those cases on the web where people use currentUser)
  • calling await fa.FirebaseAuth.instance.useAuthEmulator('localhost', 20090); inside main, prior to runApp
  • there are no calls made to googleapis like discussed in the aforementioned issue, so it doesn't seem to be a problem of "switching to use emulator too late"
  • when I log in, the authStateChanges stream correctly feeds me the updated user value, and the UI re-renders successfully with the logged in visuals
  • after reloading the page, I log two updates in the authStateChanges stream, but both of them have false for snapshot.hasData
  • when I go to the Application tab in Chrome dev tools, I do see the expected entry in Local Storage, with the user's displayName, email, and other various fields present as expected
  • when I switch setPersistence to Persistence.SESSION, the aforementioned entry starts showing up in Session Storage
  • probably irrelevant, but I use the html renderer (to work around image loading CORS issues), which I don't think is the default. The command I use to run the app is flutter run -d chrome --web-renderer html

Not sure what other helpful info I can provide. This has been a very frustrating experience. Please help!

Addendum 1:

I do set the persistence value immediately before signing in. Don't think this matters a whole lot, but it's the code I ended up with after trying a million things. I am pretty sure, though, that without any call to setPersistence, I didn't have any entry in Local/Session Storage, i.e. it seems that the default is actually Persistence.NONE and not Persistence.LOCAL like the docs suggest.

auth.setPersistence(fa.Persistence.LOCAL)
.then((_) {
  return auth.signInWithEmailAndPassword(
    email:    emailFieldController.text,
    password: passwordFieldController.text,
  );
})
.catchError((onError) => print('Error signing in $onError'))
.then((value) => print('Successfully signed in'));

@anchann
Copy link

anchann commented Jul 16, 2022

My flutter doctor output:

[✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-x64, locale en-CA)
    • Flutter version 3.0.5 at /Users/xxx/lib/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision f1875d570e (3 days ago), 2022-07-13 11:24:16 -0700
    • Engine revision e85ea0e79c
    • Dart version 2.17.6
    • DevTools version 2.12.2

[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/xxx/Library/Android/sdk
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[!] Xcode - develop for iOS and macOS (Xcode 13.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

[✓] VS Code (version 1.68.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.40.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 12.4 21F79 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 103.0.5060.114

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 2 categories.

@nitroplr
Copy link
Author

I also tried setting the persistence to local manually before logging in like you did to no avail.

@dnkoulouris
Copy link

same problem here

@russellwheatley
Copy link
Member

It appears setPersistence() no longer works on web v9 JS SDK https://firebase.google.com/docs/reference/js/auth#setpersistence. I've just tested on a web app setting persistence on initializeAuth() and it works https://firebase.google.com/docs/reference/js/auth.md#initializeauth

I'll raise a PR using that implementation, there is an issue on the web JS SDK for this bug but it is closed: firebase/firebase-js-sdk#5481

@nitroplr
Copy link
Author

nitroplr commented Jul 19, 2022

This looks to be getting addressed here #9089

@nitroplr
Copy link
Author

Sorry I just saw this issue being mentioned as the solution...how do I access this FirebaseAuth.persistenceType() method? I'm sorry if I'm wasting anyone's time, I'm a cs student trying to navigate maintaining a flutter app after 1 class that taught flutter.

@nitroplr nitroplr reopened this Jul 19, 2022
@anchann
Copy link

anchann commented Jul 19, 2022

@nitroplr I think we're still waiting for russellwheatley's PR (#9138) to land, which will expose the underlying JS APIs to us in flutter/dart land. At least's what I think is happening. (and once the PR lands, presumably someone needs to bump the version number and release a new version of flutterfire to NPM, which may be a separate process run by someone else)

@nitroplr
Copy link
Author

Ohh alright, nice.

@darshankawar darshankawar added the triage Issue is currently being triaged. label Jul 19, 2022
@darshankawar
Copy link

Let's follow-up in original issue #9089 for further updates.
You may subscribe to the draft PR that's likely to fix this issue: #9138
Closing this as a duplicate.

@darshankawar darshankawar closed this as not planned Won't fix, can't repro, duplicate, stale Jul 19, 2022
@darshankawar darshankawar added resolution: duplicate This issue or pull request already exists and removed triage Issue is currently being triaged. labels Jul 19, 2022
@firebase firebase locked and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
resolution: duplicate This issue or pull request already exists
Projects
None yet
5 participants