I am using Firebase auth on my Flutter web app.
During a debug session, I log a user in. This succeeds and Firebase returns a User object. After I close the debug session (I am debugging on chrome), and then start a new debug session, the user is never persisted.
I have recreated a minimal example app in it entirety.
With the below code here are the steps to repro...
Open app for first time, it prints "Signed out"
Press the login button, it prints "Signed in".
End the debug session by closing chrome or stopping from vscode.
Start a new debugging session in chrome, it prints "signed out", when expected would be "signed in".
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(title: 'Flutter Demo',home: const MyHomePage(),);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
Future.sync(() async {
await Firebase.initializeApp(
options: const FirebaseOptions(
// redacted firebase creds
),
);
FirebaseAuth.instance.authStateChanges().listen((user) {
user == null ? print("signed out") : print("signed in");;
});
});
}
@override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
onPressed: () async {
FirebaseAuth.instance.signInWithEmailAndPassword(email: "[email protected]", password: "qwer1234");
},
child: const Text('Sign In'),
)
);
}
}
The issue likely stems from Chrome's debug sessions using a temporary profile that doesn't persist data.
Add a user data directory flag to your debug configuration: In launch.json (VS Code):
{
"version": "0.2.0",
"configurations": [
{
"name": "Flutter: Chrome",
"request": "launch",
"type": "dart",
"args": [
"--user-data-dir=./chrome_profile"
]
}
]
}
The --user-data-dir flag forces Chrome to use a persistent storage location between sessions, allowing Firebase's localStorage data to persist.
Open Chrome DevTools (F12) Go to Application > Storage > Local Storage Verify if Firebase entries (like firebase:authUser:...) exist after login and persist after restart.
flutter build web
flutter run -d chrome --release
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
_initializeFirebase();
}
Future<void> _initializeFirebase() async {
await Firebase.initializeApp(
options: const FirebaseOptions(
// Your Firebase config here
apiKey: "AIza...",
authDomain: "your-app.firebaseapp.com",
projectId: "your-app",
storageBucket: "your-app.appspot.com",
messagingSenderId: "123...",
appId: "1:123...:web:abc...",
),
);
// Explicitly set persistence
await FirebaseAuth.instance.setPersistence(Persistence.LOCAL);
// Listen to auth state
FirebaseAuth.instance.authStateChanges().listen((user) {
user == null ? print("signed out") : print("signed in");
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: "[email protected]",
password: "qwer1234",
);
} catch (e) {
print("Login error: $e");
}
},
child: const Text('Sign In'),
),
),
);
}
}