Reputation: 2564
Here is my code (right now the "app" is just some dummy pages)
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:flutter/foundation.dart';
// ************** Begin Auth
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = new GoogleSignIn();
Future<FirebaseUser> signInWithGoogle() async {
// Attempt to get the currently authenticated user
GoogleSignInAccount currentUser = _googleSignIn.currentUser;
if (currentUser == null) {
// Attempt to sign in without user interaction
currentUser = await _googleSignIn.signInSilently();
}
if (currentUser == null) {
// Force the user to interactively sign in
currentUser = await _googleSignIn.signIn();
}
final GoogleSignInAuthentication auth = await currentUser.authentication;
// Authenticate with firebase
final FirebaseUser user = await _auth.signInWithGoogle(
idToken: auth.idToken,
accessToken: auth.accessToken,
);
assert(user != null);
assert(!user.isAnonymous);
return user;
}
Future<Null> signOutWithGoogle() async {
debugPrint('in the SIGN OUT FUNCTION');
await _auth.signOut();
await _googleSignIn.signOut();
}
// ************** ENd Auth
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.yellow,
),
home: new SplashPage(),
routes: <String, WidgetBuilder>{
'/login': (BuildContext context) => new LoginPage(),
'/app': (BuildContext context) => new AppPage(),
},
);
}
}
class SplashPage extends StatefulWidget {
@override
State createState() => new _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
final FirebaseAuth _auth = FirebaseAuth.instance;
@override
void initState() {
super.initState();
_auth.onAuthStateChanged.firstWhere((user) => user != null).then((user) {
debugPrint('AUTH STATE HAS CHANGED');
debugPrint('user id: '+user.uid);
Navigator.of(context).pushReplacementNamed('/app');
});
new Future.delayed(new Duration(seconds: 1)).then((_) => signInWithGoogle());
}
@override
Widget build(BuildContext context) {
return new Text('splash 123');
}
}
class AppPage extends StatelessWidget {
void _logout(){
debugPrint('pressed logout button');
signOutWithGoogle();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('In Da App'),
actions: <Widget>[
new IconButton(icon: new Icon(Icons.list), onPressed: _logout),
],
),
body: new Text('Welcome'),
);
}
}
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Text('You gotta login'),
);
}
}
Why isn't onAuthStateChanged detecting when a user has logged out. Also, here is a screenshot of my console when I click the logout button.
based on the console output I can confirm that the code is in fact reaching the sign out function based on my debugPrint() that I have in there. I find it curious that the console is logging:
"Notifying auth state listeners."
and then logging right after that:
"Notified 0 auth state listeners."
Upvotes: 3
Views: 5212
Reputation: 417
You should use a StreamBuilder
to make sure your widget gets notified. If you look at onAuthStateChanged
it actually returns a Stream<FirebaseUser>
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: new StreamBuilder(
stream: _auth.onAuthStateChanged,
builder: (context, snapshot) {
// Simple case
if (snapshot.hasData) {
return AppPage();
}
return SplashPage();
},
),
);
}
}
Upvotes: 8