如何在Flutter中使用onAuthStateChanged for Firebase Auth?

时间:2018-05-17 17:32:31

标签: firebase firebase-authentication flutter

  1. 我正在使用firebase auth和google登录来处理身份验证。
  2. 截至目前,我可以使用firebase_auth / google_sign_in登录我的扑克应用。
  3. 我使用的是来自https://pub.dartlang.org/packages/firebase_auth
  4. 的firebase_auth.dart插件
  5. 我正在使用onAuthStateChanged来检测用户何时登录并且一切正常。
  6. 我的问题是:当我退出时,onAuthStateChanged似乎没有注意到
  7. 这是我的代码(现在" app"只是一些虚拟页面)

    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'),
        );
      }
    }
    

    为什么没有onAuthStateChanged检测用户何时退出。此外,这是我单击注销按钮时控制台的屏幕截图。

    enter image description here

    基于控制台输出,我可以确认代码实际上是基于我在那里的debugPrint()达到了注销功能。我觉得好奇的是控制台正在记录:

    "Notifying auth state listeners." 
    

    然后立即登录:

    "Notified 0 auth state listeners."
    

1 个答案:

答案 0 :(得分:2)

您应该使用StreamBuilder来确保您的小部件得到通知。如果您查看onAuthStateChanged,它实际上会返回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();
        },
      ),
    );
  }
}