Reputation: 572
When I have a logged user, my wrapper check for additional data and once find it will open the HomeScreen of my application.
However, the Stream Builder does not return the SignIn screen even if user successfully logout.
As I can see the Home page is built in a different tree (but how to build it in the main tree?), don't know if this should interfere.
Main code:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (kIsWeb) {
await Firebase.initializeApp(),
);
} else {
await Firebase.initializeApp();
}
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<AuthService>(
create: (_) => AuthService(),
),
],
child: GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
FocusScope.of(context).requestFocus(FocusNode());
}
},
child: MaterialApp(
theme: ThemeData(
primaryColor: appColor,
primaryColorLight: appColor,
primaryColorDark: appColor,
),
debugShowCheckedModeBanner: false,
title: 'WhyBye',
//todo: Queste righe saranno necessarie quando avremo anche la versione WEB
// home: ResponsiveLayout(
// webScreenLayout: WebScreenLayout(),
// mobileScreenLayout: MobileScreenLayout()),
//todo.
initialRoute: '/wrapper',
routes: {
'/wrapper': (context) => const Wrapper(),
'/signInScreen': (context) => const SignInScreen(),
'/signUpScreen': (context) => const SignUpScreen(),
'/registrationScreen': (context) => const RegistrationScreen(),
'/homeScreen': (context) => const HomeScreen(),
'/recoverPasswordScreen': (context) =>
const RecoverPasswordScreen(),
},
),
),
);
}
}
My Wrapper code:
class Wrapper extends StatelessWidget {
const Wrapper({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final authService = Provider.of<AuthService>(context);
return StreamBuilder<User?>(
stream: authService.user,
builder: (_, AsyncSnapshot<User?> snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
final User? user = snapshot.data;
//return user == null ? const SignInScreen() : const HomeScreen();
if (user == null) {
return const SignInScreen();
} else {
WidgetsBinding.instance
?.addPostFrameCallback((_) => asyncMethod(context));
return const Scaffold(
body: Center(
child: CircularProgressIndicator(
color: appBarColor,
),
),
);
}
} else {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(
color: appBarColor,
),
),
);
}
},
);
}
}
void asyncMethod(BuildContext context) async {
final FirebaseMethods _firebase = FirebaseMethods();
bool isTrue = await _firebase.isRegistrationUserCompleted(_firebase.getUID());
if (!isTrue) {
Variables.isCustomUserPic = false;
Variables.isSocialUserPic = false;
await _firebase.loadDefaultUserPicUrl();
//& qui devo andare alla registrazione utente.
if (Variables.isSignUp) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const RegistrationScreen()),
);
} else {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const RegistrationScreen()),
);
}
//Navigator.pop(context);
} else {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
//Navigator.pop(context);
}
}
And my very simple Home Screen:
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return const IHome();
}
}
class IHome extends StatelessWidget {
const IHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Center(
child: ElevatedButton(
child: const Text('LogOut'),
onPressed: () async {
bool isTrue = await AuthMethods().signOut();
if (isTrue) {
//Navigator.pop(context);
}
//Navigator.pop(context);
},
),
),
);
}
}
here the widget tree when a user is logged in and the wrapper loads the Home Screen.
As you can see I need to check other data before to switch to Home Screen, it's a post-account data that I need.
However when a user is logged in I open the Home Page directly from the Wrapper, but the Logout is not recognised (I checked the logout works well).
Here the widget tree when the wrapper chose the SignIn screen (because the user is not logged in).
As I should understand I probably need to avoid to use Navigator to open HomeScreen, but I don't know how to do.
Many thanks for support.
Upvotes: 3
Views: 1326
Reputation: 171
There could be a couple of reasons why you don't get rerouted when the authStatechange
:
could be a major issue with how your provider
and state notifiers
are created and are being used.
I suggest you listen for authStateChange
in your Wrapper Widget
instead, here is a brief example:
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Your App Name',
home: _getLandingPage()
);
}
Widget _getLandingPage() {
return StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return MainPage();
} else {
return LoginPage();
}
},
);
}
OR
FirebaseAuth.instance
.userChanges()
.listen((User? user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});
You can find more info here
Upvotes: 1