首页 文章

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

提问于
浏览
0
  • 我正在使用firebase auth和谷歌登录来处理身份验证 .

  • 截至目前,我可以使用firebase_auth / google_sign_in登录我的扑动应用程序 .

  • 我使用的是firebase_auth.dart插件:https://pub.dartlang.org/packages/firebase_auth

  • 我正在使用onAuthStateChanged来检测用户何时登录并且一切正常 .

  • 我的问题是:当我退出时,onAuthStateChanged似乎没有注意到

这是我的代码(现在“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 回答

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

相关问题