每当用户关闭应用程序时,他们都必须重新登录。我查看并尝试实现 authStateChanges。但是我的应用程序仍然强制用户在关闭应用程序后重新登录。在 App 类中,您可以看到我尝试完全执行 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。
你需要什么:
对于最新版本和明显较旧的版本。
步骤 0:添加所需的依赖项并运行 flutter pub get。这一个是没有道理的。
第一步:制作
auth_services
类(class):代码如下
对于旧版本的
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;
}
}
解释:我已经制作了这个类来处理所有的身份验证函数。我正在制作一个名为 onAuthStateChanged 的函数,它返回一个 User 类型的流(旧版本的 firebase auth 的 id),我将收听这个流以查明是否有用户登录。第 2 步:创建将包装整个应用程序的身份验证提供程序,并使其可以在应用程序的任何位置获取我们的用户 ID。
创建一个名为 auth_provider.dart 的文件。
代码如下。
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>());
}
下一步是将整个应用程序包装在此提供程序小部件中,并将主 Controller 设置为主页。第 3 步:在 main.dart 文件或其他任何地方,创建一个名为 HomeController 的类来处理登录状态,并将 home Controller 设置为分配的主页。
注意:我设置了一个黑色容器,在加载应用程序时显示,以确定用户是否登录。这是一个相当快的过程,但如果您愿意,您可以将其设置为应用程序主题颜色的容器。您甚至可以将其设置为启动画面。 (请注意。这个容器最多显示大约 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,
);
},
);
}
}
说明:家庭 Controller 只是一个 Steam 生成器,它监听我们所做的 auth 更改。如果有任何东西,则用户已登录。如果没有,则他已注销。相当简单。尽管在确定用户的登录状态之间存在 1 秒的延迟。苏,那段时间我要退回一个黑色的容器。用户在打开应用程序后会看到屏幕变黑约一秒钟,然后出现轰鸣声。主页重要提示:您应该使用提供程序包装整个应用程序。这个很重要。请不要忘了。
如何在应用程序中的任何时候获取用户 ID
Provider.of(context).auth.getCurrentUID()
你去吧。享受[编辑]正如 L. Gangemi 所说,新版本的 Firebase Auth 返回用户流。所以将家庭 Controller 代码编辑为
builder: (context, AsyncSnapshot<User> snapshot) {
关于firebase - 挣扎于 Flutter 中的 authStateChanges,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64520543/