每当用户关闭应用程序时,他们都必须重新登录.我查看并try 实现authStateChanges.但我的应用程序仍在强迫用户在关闭应用程序后重新登录.在App类中,您可以看到我try 执行authStateChange,但不幸的是似乎什么都没有发生.

Future<void> main() async {


WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(App());
}

// Firebase Auth Instance
FirebaseAuth auth = FirebaseAuth.instance;

class MyApp extends StatelessWidget {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();



// This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
  title: 'Tanbo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  home: LoginPage(),
);


}
}

// This is the main root screen of the Tanbo app
class App extends StatelessWidget {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();



@override
  Widget build(BuildContext context) {
    return FutureBuilder(
      // Initialize FlutterFire
      future: _initialization,
  

builder: (context, snapshot) {
    final user = FirebaseAuth.instance.authStateChanges().listen((User user) {
      if (user == null) {
        print('User signed out');
      } else {
        print('User signed in');
      }
    });

    // Check for errors
    if (snapshot.hasError) {
      return ErrorHandler();
    }

    // Once complete, show your application
    if (snapshot.connectionState == ConnectionState.done) {
      // If the user isn't logged in, we will be sent to sign up page.
      if (user != null) {
        return MyApp();
      } else {
        // If the user is logged in, TabHandler will be shown.
        return TabHandler();
      }
    }

    // Otherwise, show something whilst waiting for initialization to complete
    return LoadingHandler();
  },
);


 }
}

推荐答案

问题是您已经显式地将您的登录页面作为您的主页.当应用程序打开时,它将自动读取main.dart文件,并将登录页面视为分配的主页.

这就是你修复它的方法.还可以制作一个身份验证系统,在该系统中,你可以在应用程序的任何位置获取登录用户的ID.

您需要的:

  1. 提供程序依赖于哪个版本.最好是最新的
  2. 微笑--别皱眉了.你就要解决你的问题了
  3. FireBase身份验证依赖项.无论哪个版本.我要给你打一针 适用于最新版本,也适用于明显较旧的版本.

第0步:添加所需的依赖项并运行flatter pub get.这是一个不需要动脑筋的问题.

第一步:上auth_services级:

对于旧版本的firebase auth:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

class AuthService {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
  final GoogleSignIn _googleSignIn = GoogleSignIn();

  Stream<String> get onAuthStateChanged =>
      _firebaseAuth.onAuthStateChanged.map(
            (FirebaseUser user) => user?.uid,
      );

  // GET UID
  Future<String> getCurrentUID() async {
    return (await _firebaseAuth.currentUser()).uid;
  }
}

对于较新版本的FireBase身份验证依赖关系:

class AuthService {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
  final GoogleSignIn _googleSignIn = GoogleSignIn();

  Stream<User> get onAuthStateChanged => _firebaseAuth.authStateChanges();

  // GET UID
  Future<String> getCurrentUID() async {
    return _firebaseAuth.currentUser.uid;
  }
}

说明:我制作了这个类来处理所有的auth函数.我正在创建一个名为onAuthStateChanged的函数,该函数返回一个USER类型的流(旧版本的Firebase auth的ID),我将侦听该流,以确定是否有用户登录.

第2步:创建一个身份验证提供者,它将包装整个应用程序,并使我们能够在应用程序中的任何位置获取用户id.

创建一个名为auth_provider的文件.飞奔

import 'package:flutter/material.dart';
import 'auth_service.dart';

class Provider extends InheritedWidget {
  final AuthService auth;
  Provider({
    Key key,
    Widget child,
    this.auth,
  }) : super(key: key, child: child);

  @override
  bool updateShouldNotify(InheritedWidget oldWiddget) {
    return true;
  }

  static Provider of(BuildContext context) =>
      (context.dependOnInheritedWidgetOfExactType<Provider>());
}

下一步是将整个应用程序包装在此提供程序小部件中,并将家庭控制器设置为主页.

步骤3:在main.dart文件中,或者实际上在任何地方,创建一个名为HomeController的类,它将处理登录状态,并将Home Controller设置为指定的主页.

注:我已经设置了一个黑色容器,在应用程序加载时显示,以确定用户是否登录.这是一个相当快的过程,但是如果你愿意,你可以将它设置为你的应用程序主题 colored颜色 的容器.您甚至可以将其设置为闪屏.(请注意.这个容器最多只能显示1秒左右.(根据我的经验)

代码如下: 进口所有必需的东西

void main() {
 //WidgetsFlutterBinding.ensureInitialized();
 // await Firebase.initializeApp();
//only add these if you're on the latest firebase
  runApp(MyApp());
}

 class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider(
      auth: AuthService(),
      child: MaterialApp(
            title: 'Dreamora',
            theme: ThemeData(
              // fontFamily: "Montserrat",
              brightness: Brightness.light,
              inputDecorationTheme: InputDecorationTheme(
                contentPadding:
                    EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(5.0),
                ),
              ),
              primarySwatch: Colors.purple,
              visualDensity: VisualDensity.adaptivePlatformDensity,
            ),
            home: HomeController(),
          );
        },
      ),
    ),}
//(I think i have messed up the brackets here, but, you get the 
//gist)

class HomeController extends StatelessWidget {
  const HomeController({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final AuthService auth = Provider.of(context).auth;

    return StreamBuilder(
      stream: auth.onAuthStateChanged,
      builder: (context, AsyncSnapshot<String> snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          final bool signedIn = snapshot.hasData;
          return signedIn ? DashBoard() : FirstView();
        }
        return Container(
          color: Colors.black,
        );
      },
    );
  }
}

说明:家用控制器只是一个蒸汽生成器,它倾听我们所做的大量更改.如果有任何内容,则用户已登录.如果没有,他将被注销.相当简单.虽然在确定用户的登录状态之间有大约1秒的延迟.苏,在那段时间里我会归还一个黑色的集装箱.打开应用程序后,用户将看到屏幕变黑约一秒钟,然后轰隆作响.主页

重要提示:你应该使用Provider 包装你的整个应用程序.这很重要.别忘了.

如何在应用程序中随时获取用户ID

Provider.of(context).auth.getCurrentUID()

好了.享受

[编辑]正如L.Gangemi所说,新版本的Firebase Auth返回用户流.因此,将主控制器代码编辑为

builder: (context, AsyncSnapshot<User> snapshot) {

Dart相关问答推荐

将数据库提供程序导入另一个文件提供程序 dart

Flutter:是否可以有多个 Futurebuilder 或一个 Futurebuilder 用于多个 Future 方法?

Flutter 中带有导航栏的永久视图

Dart 1.8 中的异步/等待功能

执行 `dart2js` 时会生成哪些文件?为什么?

如何在 Dart 中设置文本框的值?

Flutter - 在 null 上调用了 getter 'length'

从列表中删除项目后更新 UI

LinearProgressIndicator Flutter使用

了解Dart private class

从real mobile浏览器访问Flatter localhost

常数在定义Flutter边缘集中的作用

Dart 交互/访问数据库

Opa vs Dart vs Haxe vs CoffeeScript

Dart:并行处理传入的 HTTP 请求

Dart:异步抽象方法

Dart 中 == 和 === 有什么区别?

Dart 的服务器端框架

Dart MD5 字符串

是否可以在 Dart 中的一行上初始化列表?