Gil*_*erg 11 dart firebase firebase-authentication google-signin flutter
在Flutter之外,当我实现firebase身份验证时,我总是使用firebase提供的onAuthStateChanged侦听器来确定用户是否已登录并相应地做出响应.
我正在尝试使用flutter做类似的事情,但我可以找到一种方法来访问Firebase的onAuthStateChanged.我正在使用firebase_auth和google_signin Flutter插件.我正在使用firebase_auth Flutter插件中包含的示例代码.下面是示例代码.我可以使用谷歌登录成功登录,但示例太简单了,因为我想让观察者/监听器检测用户的登录/退出状态.
有没有办法通过观察者/监听器使用firebase_auth/google_signin flutter插件来检测以确定用户的状态?
最终,我希望应用程序确定用户是否已登录(是/否).如果没有,则显示登录屏幕,如果是,则显示我的主应用程序页面.
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = new GoogleSignIn();
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Firebase Auth Demo',
home: new MyHomePage(title: 'Firebase Auth Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<String> _message = new Future<String>.value('');
Future<String> _testSignInAnonymously() async {
final FirebaseUser user = await _auth.signInAnonymously();
assert(user != null);
assert(user == _auth.currentUser);
assert(user.isAnonymous);
assert(!user.isEmailVerified);
assert(await user.getToken() != null);
if (Platform.isIOS) {
// Anonymous auth doesn't show up as a provider on iOS
assert(user.providerData.isEmpty);
} else if (Platform.isAndroid) {
// Anonymous auth does show up as a provider on Android
assert(user.providerData.length == 1);
assert(user.providerData[0].providerId == 'firebase');
assert(user.providerData[0].uid != null);
assert(user.providerData[0].displayName == null);
assert(user.providerData[0].photoUrl == null);
assert(user.providerData[0].email == null);
}
return 'signInAnonymously succeeded: $user';
}
Future<String> _testSignInWithGoogle() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final FirebaseUser user = await _auth.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
assert(user.email != null);
assert(user.displayName != null);
assert(!user.isAnonymous);
assert(await user.getToken() != null);
return 'signInWithGoogle succeeded: $user';
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new MaterialButton(
child: const Text('Test signInAnonymously'),
onPressed: () {
setState(() {
_message = _testSignInAnonymously();
});
}),
new MaterialButton(
child: const Text('Test signInWithGoogle'),
onPressed: () {
setState(() {
_message = _testSignInWithGoogle();
});
}),
new FutureBuilder<String>(
future: _message,
builder: (_, AsyncSnapshot<String> snapshot) {
return new Text(snapshot.data ?? '',
style: const TextStyle(
color: const Color.fromARGB(255, 0, 155, 0)));
}),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是有问题的flutter包的链接:https : //github.com/flutter/plugins/tree/master/packages/firebase_auth https://github.com/flutter/plugins/tree/master/packages/google_sign_in
Jav*_*ash 23
我知道这个问题已经很老了,但如果有人还在寻找,那么这就是答案.
Firebase使用onAuthStateChanged函数返回FirebaseUser流.有许多方法可以监听用户的身份验证状态更改.我是这样做的:
解决方案1
我将StreamBuilder返回到我的应用程序主页,StreamBuilder根据用户的身份验证状态返回特定页面.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Your App Name',
home: _getLandingPage()
);
}
Widget _getLandingPage() {
return StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data.providerData.length == 1) { // logged in using email and password
return snapshot.data.isEmailVerified
? MainPage()
: VerifyEmailPage(user: snapshot.data);
} else { // logged in using other providers
return MainPage();
}
} else {
return LoginPage();
}
},
);
}
Run Code Online (Sandbox Code Playgroud)
解决方案2
您也可以在应用程序的initState()
功能中创建一个监听器.
@override
void initState() {
super.initState();
FirebaseAuth.instance.onAuthStateChanged.listen((firebaseUser) {
// do whatever you want based on the firebaseUser state
});
}
Run Code Online (Sandbox Code Playgroud)
Cop*_*oad 11
截屏:
要检查用户是否从应用程序的任何位置登录,请使用
bool signedIn = Auth.instance.isSignedIn;
Run Code Online (Sandbox Code Playgroud)
要登录,请使用
await Auth.instance.signIn(email: 'email', password: 'password');
Run Code Online (Sandbox Code Playgroud)
要退出,请使用
await Auth.instance.signOut();
Run Code Online (Sandbox Code Playgroud)
完整代码:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MaterialApp(
home: StreamBuilder<User?>(
stream: Auth.instance.authStateChange(),
builder: (_, snapshot) {
final isSignedIn = snapshot.data != null;
return isSignedIn ? HomePage() : LoginPage();
},
),
),
);
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('HomePage')),
body: Center(
child: ElevatedButton(
onPressed: () => Auth.instance.signOut(),
child: Text('Sign out'),
),
),
);
}
}
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('LoginPage')),
body: Center(
child: ElevatedButton(
onPressed: () => Auth.instance.signIn(email: 'test@test.com', password: 'test1234'),
child: Text('Sign in'),
),
),
);
}
}
class Auth {
static final instance = Auth._();
Auth._();
final FirebaseAuth _auth = FirebaseAuth.instance;
bool get isSignedIn => _auth.currentUser != null;
Stream<User?> authStateChange() => _auth.authStateChanges();
Future<void> signIn({required String email, required String password}) => _auth.signInWithEmailAndPassword(email: email, password: password);
Future<void> signOut() => _auth.signOut();
}
Run Code Online (Sandbox Code Playgroud)
使用provider
包的相同代码:
检查这个答案:
您可以在 AuthService 类中创建一个流作为 onAuthStateChanged 的 getter。为了帮助您管理状态,您可以使用 Provider 包。AuthService 类将扩展 ChangeNotifier 类。
class AuthService extends ChangeNotifier {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = new GoogleSignIn();
// create a getter stream
Stream<FirebaseUser> get onAuthStateChanged => _auth.onAuthStateChanged;
//Sign in async functions here ..
}
Run Code Online (Sandbox Code Playgroud)
用 ChangeNotifierProvider 包裹你的 MaterialApp 并在 create 方法中返回一个 AuthService 类的实例,如下所示:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => AuthService(),
child: new MaterialApp(
title: 'Firebase Auth Demo',
home: Landing(),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
现在将登陆页面创建为无状态小部件。使用 Provider.of(context) 和流构建器来侦听身份验证更改并根据需要呈现登录页面或主页。
class Landing extends StatelessWidget {
@override
Widget build(BuildContext context) {
AuthService auth = Provider.of<AuthService>(context);
return StreamBuilder<FirebaseUser>(
stream: auth.onAuthStateChanged,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
FirebaseUser user = snapshot.data;
if (user == null) {
return LogIn();
}
return Home();
} else {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以从官方 flutter 文档中阅读有关使用 provider 进行状态管理的更多信息。按照此链接:https : //flutter.dev/docs/development/data-and-backend/state-mgmt/simple
在火力地堡颤振程式码实验室有使用谷歌标志和火力地堡AUTH一个更深入的例子。
完成最后一步后,您将获得此_ensureLoggedIn
功能,该功能用于检查用户是否已登录,如果未登录,则启动登录流程。
Future<Null> _ensureLoggedIn() async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null)
user = await googleSignIn.signInSilently();
if (user == null) {
user = await googleSignIn.signIn();
analytics.logLogin();
}
if (auth.currentUser == null) {
GoogleSignInAuthentication credentials =
await googleSignIn.currentUser.authentication;
await auth.signInWithGoogle(
idToken: credentials.idToken,
accessToken: credentials.accessToken,
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以修改此选项,以在应用启动时检查这些内容,并有条件地向预身份验证和后身份验证用户显示不同的视图,例如:
final auth = FirebaseAuth.instance;
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'MyApp',
home: (_checkLogin() == true ? new PostAuthScaffold() : new PreAuthScaffold())
);
}
}
bool _checkLogin() {
GoogleSignInAccount user = googleSignIn.currentUser;
return !(user == null && auth.currentUser == null);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11309 次 |
最近记录: |