【问题标题】:Flutter firebase auth doesn't persist after app is killed应用程序被杀死后,Flutter firebase auth 不会持续存在
【发布时间】:2021-02-14 14:30:26
【问题描述】:

我正在尝试通过使用文档中的此代码将 firebase 身份验证状态保持在颤振应用程序中,但是当我在模拟器中终止应用程序并再次打开它时,它无法识别用户。 我可以使用 sharedpreferences 但我只想使用 firebase,我在这里做错了什么?

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // Create the initialization Future outside of `build`:
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
  final FirebaseAuth auth = FirebaseAuth.instance;

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      // Initialize FlutterFire:
      future: _initialization,
      builder: (context, snapshot) {
        // Check for errors
        if (snapshot.hasError) {
          return (MaterialApp(
            home: Warning(
              warning: 'Error',
            ),
          ));
        }
        // once complete show your app
        if (snapshot.connectionState == ConnectionState.done) {
          print('CONNECTED');

          if (AuthService().user() == null) {
            return MaterialApp(
              home: LoginPage(),
            );
          } else {
            return MaterialApp(
              home: HomePage(),
            );
          }
        }
        // if nothing happens return loading
        return MaterialApp(
          home: //LoginPage()
              Warning(
            warning: 'Loading',
          ),
        );
      },
    );
  }
}

AuthService 类

导入'package:firebase_auth/firebase_auth.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // auth change user stream
  User user() {
    // ignore: deprecated_member_use
    _auth.authStateChanges().listen((User user) {
      if (user == null) {
        return null;
      } else {
        return user;
      }
    });
  }
}

希望你能帮助我理解问题并解决它,谢谢。

【问题讨论】:

    标签: firebase flutter firebase-authentication


    【解决方案1】:

    由于authStateChanges 返回Stream,因此您也需要在代码中使用StreamBuilder 来包装该异步操作。

    类似这样的:

    // once complete show your app
    if (snapshot.connectionState == ConnectionState.done) {
      print('CONNECTED');
      return StreamBuilder(
        stream: FirebaseAuth.instance. authStateChanges(),
        builder: (BuildContext context, snapshot) {
          if (snapshot.hasData) {
            return MaterialApp(
              home: LoginPage(),
            );
          } else {
            return MaterialApp(
              home: HomePage(),
            );
          }
        }
      )
    }
    

    不相关:您经常重复创建MaterialApp 的代码,这不是必需的。例如,在上面的 sn-p 中,我们可以只提及一次 MaterialApp,并得到相同的结果:

    // once complete show your app
    if (snapshot.connectionState == ConnectionState.done) {
      print('CONNECTED');
      return StreamBuilder(
        stream: FirebaseAuth.instance. authStateChanges(),
        builder: (BuildContext context, snapshot) {
          return MaterialApp(
            home: snapshot.hasData && snapshot.data != null ? HomePage() : LoginPage(),
          )
        }
      )
    }
    

    如果您对所有提及 MaterialApp 和其他重复项都这样做,您可以显着减少代码,使其不易出错且更易于维护。

    【讨论】:

    • 非常感谢,第二个代码块运行良好,第一个代码块显示主页,然后显示登录页面,我看到两者之间的唯一区别是snapshot.data != null 部分
    【解决方案2】:

    它确实存在。您只是没有正确使用身份验证状态侦听器。来自authStateChanges 侦听器的返回语句实际上并没有逃避对user() 的调用。最重要的是,侦听器可以在第一次返回 null。直到一段时间后,Firebase SDK 才确定用户实际有效并已登录。届时您的侦听器将收到第二次回调。您的代码需要为此做好准备 - 它不能盲目地取第一个值,因为身份验证状态可能会随着时间而改变。

    我建议在您的身份验证状态侦听器中添加一些调试日志,以了解其实际工作原理。我还建议reading this blog 更详细地了解身份验证状态侦听器的工作原理。

    【讨论】:

    • 感谢您的评论,现在我明白为什么会这样了
    【解决方案3】:

    你可以使用我的代码,你可以使用 userChanges() 代替 authStateChanges()

    final Stream<User?> firebaseUserChanges = firebaseAuth.userChanges();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      相关资源
      最近更新 更多