onAuthStateChanged를 사용한 Float을 사용한 Firebase 로그인
Flutter 이외에서는 Firebase 인증을 구현할 때 항상 Firebase에서 제공하는 onAuthStateChanged 수신기를 사용하여 사용자가 로그인했는지 여부를 확인하고 그에 따라 응답합니다.
Flooth를 이용해서 비슷한 것을 하려고 하는데, Firebase의 AuthStateChanged에서 접근할 수 있는 방법을 찾을 수 있습니다.firebase_auth 및 google_signin Flutter 플러그인을 사용하고 있습니다.저는 firebase_auth Flutter 플러그인에 포함된 예제 코드를 작업하고 있습니다.아래는 샘플 코드입니다.Google 로그인으로 성공적으로 로그인할 수 있지만, 사용자의 로그인/로그아웃 상태를 감지할 수 있는 관찰자/청취자가 필요하기 때문에 예제가 너무 간단합니다.
firebase_auth/google_signinflating 플러그인을 사용하여 관찰자/청취자를 통해 사용자의 상태를 감지하는 방법이 있습니까?
궁극적으로 앱에서 사용자가 로그인했는지 여부(예/아니오)를 확인하기를 원합니다.그렇지 않으면 로그인 화면을 표시하고, 그렇지 않으면 기본 앱 페이지를 표시합니다.
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)));
}),
],
),
);
}
}
다음은 문제의 플라우터 패키지에 대한 링크입니다: https://github.com/flutter/plugins/tree/master/packages/google_sign_in https://github.com/flutter/plugins/tree/master/packages/firebase_auth
저는 이 질문이 꽤 오래된 것이라는 것을 알지만, 여전히 그것을 찾고 있는 사람이 있다면 여기 답이 있습니다.
에서 Firebase를 합니다.Stream
FirebaseUser
그것과 함께onAuthStateChanged
기능. 들을 수 있는 은 여러 .사용자의 인증 상태 변경을 청취하는 방법은 여러 가지가 있습니다.이렇게 해야 합니다.
솔루션 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();
}
},
);
}
솔루션 2
당신은 에서 수 .initState()
기능도 합니다.수신기를 등록하기 전에 파이어베이스 앱이 초기화되었는지 확인합니다.
@override
void initState() {
super.initState();
FirebaseAuth.instance.authStateChanges().listen((firebaseUser) {
// do whatever you want based on the firebaseUser state
});
}
솔루션 3(2021년 5월 업데이트)
공급자 패키지를 사용하지 않고 null-safety를 사용하는 간단한 접근 방식:
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(App());
}
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
/// State is persistent and not rebuilt, therefore [Future] is only created once.
/// If [StatelessWidget] is used, in the event where [App] is rebuilt, that
/// would re-initialize FlutterFire and makes our app re-enter the
/// loading state, which is undesired.
class _AppState extends State<App> {
final Future<FirebaseApp> _initFirebaseSdk = Firebase.initializeApp();
final _navigatorKey = new GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: _navigatorKey,
theme: theme(),
home: FutureBuilder(
future: _initFirebaseSdk,
builder: (_, snapshot) {
if (snapshot.hasError) return ErrorScreen();
if (snapshot.connectionState == ConnectionState.done) {
// Assign listener after the SDK is initialized successfully
FirebaseAuth.instance.authStateChanges().listen((User? user) {
if (user == null)
_navigatorKey.currentState!
.pushReplacementNamed(LoginScreen.routeName);
else
_navigatorKey.currentState!
.pushReplacementNamed(HomeScreen.routeName);
});
}
return LoadingScreen();
}),
routes: routes,
);
}
}
인증 ▁use▁fire다▁this▁guarant니ees▁only▁you▁that만 사용하도록 보장합니다.FirebaseAuth.instance.authStateChanges().listen()
SDK가 초기화를 완료한 후.앱 실행 시 인증 변경 수신기가 먼저 호출되고 로그아웃 및 로그인 후 자동으로 다시 호출됩니다.
.pushReplacementNamed()
하지 않고 새).
Null 안전 코드(타사 패키지 제외)
스크린샷:
사용자가 앱의 아무 곳에서나 로그인했는지 확인하려면 다음을 사용합니다.
bool signedIn = Auth.instance.isSignedIn;
로그인하려면, 사용
await Auth.instance.signIn(email: 'email', password: 'password');
로그아웃하려면, 사용
await Auth.instance.signOut();
전체 코드:
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();
}
다음을 사용하는 동일한 코드provider
패키지:
다음 답변 확인:
AuthService 클래스 내에서 onAuthStateChanged에 대한 getter로 스트림을 생성할 수 있습니다.상태를 관리하는 데 도움이 되도록 공급자 패키지를 사용할 수 있습니다.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 ..
}
MaterialApp을 ChangeNotifierProvider로 래핑하고 AuthService 클래스의 인스턴스를 다음과 같이 생성 메서드로 반환합니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => AuthService(),
child: new MaterialApp(
title: 'Firebase Auth Demo',
home: Landing(),
),
);
}
}
이제 시작 페이지를 상태 비저장 위젯으로 만듭니다.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(),
),
);
}
},
);
}
}
공급자를 사용한 상태 관리에 대한 자세한 내용은 공식 문서를 참조하십시오.다음 링크를 따르십시오. https://flutter.dev/docs/dev/docs/data-and-backend/state-mgmt/simple
Flutter Codelab용 Firebase에는 Google 로그인 및 Firebase 인증을 사용한 훨씬 더 자세한 예제가 있습니다.
마지막 단계 후에 당신은 이것으로 끝납니다._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,
);
}
}
이를 수정하여 앱이 시작될 때 이러한 사항을 확인하고 다음과 같은 방법으로 사전 인증 및 사후 인증 사용자에게 조건부로 다른 보기를 표시할 수 있습니다.
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);
}
code(Null provider
):
전체 코드:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MaterialApp(
home: ChangeNotifierProvider(
create: (_) => AuthModel(),
child: Consumer<AuthModel>(
builder: (_, model, __) => model.isSignedIn ? HomePage() : LoginPage(),
),
),
),
);
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('HomePage')),
body: Center(
child: ElevatedButton(
onPressed: () async {
final model = context.read<AuthModel>();
await model.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: () async {
final model = context.read<AuthModel>();
await model.signIn(email: 'test@test.com', password: 'test1234');
},
child: Text('Sign in'),
),
),
);
}
}
class AuthModel extends ChangeNotifier {
final FirebaseAuth _auth = FirebaseAuth.instance;
bool get isSignedIn => _auth.currentUser != null;
Future<void> signIn({required String email, required String password}) async {
await _auth.signInWithEmailAndPassword(email: email, password: password);
notifyListeners();
}
Future<void> signOut() async {
await _auth.signOut();
notifyListeners();
}
}
인증 상태 변경 정보를 얻기 위해 공유 기본 설정을 사용한 것과 동일한 쿼리가 있습니다. 또한 Firebase 및 Floot와 함께 공유 기본 설정을 사용하여 프로젝트를 만들었습니다.만약 당신이 알고 싶다면, 당신은 제가 쓴 같은 블로그를 읽을 수 있습니다.
Firebase 구현Flutter에서 공유 기본 설정을 사용하는 AuthStateListener." https://medium.com/ @vaibhavminiar/fluting-firebaseauthstatelistener-using-shared-references-in-fluter-b42e12f81eb2
Floatter Fire의 마지막 업데이트 이후로 당신은 이렇게 해야 합니다.
FirebaseAuth.instance.authStateChanges().listen((User user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
}
);
이 상태에 실시간으로 할 수 .
Stream
일단 호출되면 스트림은 사용자의 현재 인증 상태에 대한 즉시 이벤트를 제공한 다음 인증 상태가 변경될 때마다 후속 이벤트를 제공합니다.이러한 변경 내용을 구독하려면 다음 번호로 문의하십시오.
authStateChanges()
당신의 방법FirebaseAuth
사례.스트림은 다음과 같은 경우 사용자 클래스를 반환합니다.
user
로그인됨, 또는null
그들이 아니라면요.아래에서 사용자 관리에 대한 자세한 내용을 읽을 수 있습니다.
언급URL : https://stackoverflow.com/questions/45353730/firebase-login-with-flutter-using-onauthstatechanged
'programing' 카테고리의 다른 글
Oracle: 열 순서가 인덱스에서 중요합니까? (0) | 2023.07.17 |
---|---|
그래프(데이터 구조)를 Python으로 표현 (0) | 2023.07.17 |
오라클 번호 형식의 원치 않는 선행 공백 (0) | 2023.07.07 |
에서 포스트백 사용 안 함 (0) | 2023.07.07 |
Spring boot 2.1.0 스타터 구성에서 spring.main.allow-bean-definition-overriding을 true로 설정하는 방법 (0) | 2023.07.07 |