gpt4 book ai didi

firebase - flutter firebase 谷歌注销不工作

转载 作者:行者123 更新时间:2023-12-01 21:51:58 25 4
gpt4 key购买 nike

我正在尝试实现谷歌登录/注销,但我的注销不起作用。我收到一个错误 signOut() was called on null。当我在用户登录后打印出用户时,我确实获得了所有正确的信息,但是当我在我的注销功能中打印出时,它说它是空的。自定义 firebase 用户确实有效。这是我的 auth.dart 文件:

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

abstract class BaseAuth {
Future<String> signIn(String email, String password);

Future<String> signUp(String email, String password);

Future<FirebaseUser> getCurrentUser();

Future<void> sendEmailVerification();

Future<void> signOut();

Future<bool> isEmailVerified();

Future<String> signInWithGoogle();
}

class Auth implements BaseAuth {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
FirebaseUser user;

Future<String> signIn(String email, String password) async {

user = (await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password)).user;
return user.email;
}

Future<String> signUp(String email, String password) async {
FirebaseUser user = (await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password)).user;
return user.uid;
}

Future<FirebaseUser> getCurrentUser() async {
user = await _firebaseAuth.currentUser();
return user;
}
signOut() async {
//print("signed in user: ${authService.user}");
await _firebaseAuth.signOut();
}

Future<void> sendEmailVerification() async {
FirebaseUser user = await _firebaseAuth.currentUser();
user.sendEmailVerification();
}

Future<bool> isEmailVerified() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user.isEmailVerified;
}

Future<String> signInWithGoogle() async {
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;

final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);

user = (await _firebaseAuth.signInWithCredential(credential)).user;

assert(!user.isAnonymous);
assert(await user.getIdToken() != null);

final FirebaseUser currentUser = await _firebaseAuth.currentUser();
assert(user.uid == currentUser.uid);
return 'signInWithGoogle succeeded: $user';
}

}


还有一件奇怪的事情是,如果我启动应用程序并且已经登录(作为谷歌),我点击注销并且它似乎可以正常工作。我的控制台中没有任何内容,但它会返回到登录屏幕。然后,如果我以 google 身份重新登录并注销,就会开始发生错误。另一件奇怪的事情是,如果我碰巧已经登录了,我点击一下就退出了,如果我在 android studio 中重新启动我的应用程序,它不会改变任何东西,它会让我回到我应该已经登录的屏幕。这只发生在 Google 注销(不是 firebase 注销)时。知道我可能做错了什么吗?谢谢

pubspec.yaml

dependencies:
firebase_auth: ^0.14.0+5

firebase_database: ^3.0.7
google_sign_in: ^4.0.7
firebase_storage:
image_picker:
cloud_firestore:
shared_preferences:
fluttertoast:
cached_network_image:
intl:

我使用它的一个页面:(我有很多,但实现方式与此类似,但它在我的任何页面中都不起作用)

import 'package:flutter/material.dart';
import 'package:pet_helper/chat.dart';
import 'package:pet_helper/lost_and_found.dart';
import 'package:pet_helper/pet_adoption.dart';
import 'authentication.dart';

class HomePage extends StatefulWidget {
HomePage({Key key, this.auth, this.userId, this.onSignedOut})
: super(key: key);

final BaseAuth auth;
final VoidCallback onSignedOut;
final String userId;

@override
State<StatefulWidget> createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {

final GlobalKey<FormState> formKey = GlobalKey<FormState>();
int _currentIndex = 0;

@override
void initState() {
super.initState();
}
final List<Widget> _children = [
new LostAndFoundPage(),
new PetAdoptionPage(),
new ChatPage(),
];
_signOut() async {
try {
await widget.auth.signOut();
widget.onSignedOut();
} catch (e) {

print(e);
}
}

onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
automaticallyImplyLeading:false,
title: new Text('Pet Helper'),
actions: <Widget>[
new FlatButton(
child: new Text('Logout',
style: new TextStyle(fontSize: 17.0, color: Colors.white)),
onPressed: _signOut)
],
),
body: _children[_currentIndex], // new
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped, // new
currentIndex: _currentIndex, // new
items: [
new BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Lost & Found'),
),
new BottomNavigationBarItem(
icon: Icon(Icons.pets),
title: Text('Pet Adoption'),
),
new BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Chat'))
],
));
}
}

为了完成,这是我的登录页面:


import 'package:flutter/material.dart';
import 'package:pet_helper/home_page.dart';
import 'authentication.dart';

class LoginSignUpPage extends StatefulWidget {
LoginSignUpPage({this.auth, this.onSignedIn});

final BaseAuth auth;
final VoidCallback onSignedIn;

@override
State<StatefulWidget> createState() => new _LoginSignUpPageState();
}

enum FormMode { LOGIN, SIGNUP }
class _LoginSignUpPageState extends State<LoginSignUpPage> {
final _formKey = new GlobalKey<FormState>();
String _email;
String _password;
String _errorMessage;

// Initial form is login form
FormMode _formMode = FormMode.LOGIN;
bool _isIos;
bool _isLoading;

// Check if form is valid before perform login or signup
bool _validateAndSave() {
final form = _formKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}

// Perform login or signup
void _validateAndSubmit() async {
setState(() {
_errorMessage = "";
_isLoading = true;
});
if (_validateAndSave()) {
String userId = "";
try {
if (_formMode == FormMode.LOGIN) {
userId = await widget.auth.signIn(_email, _password);
print('Signed in: $userId');
} else {
userId = await widget.auth.signUp(_email, _password);
widget.auth.sendEmailVerification();
_showVerifyEmailSentDialog();
print('Signed up user: $userId');
}
setState(() {
_isLoading = false;
});

if (userId.length > 0 && userId != null && _formMode == FormMode.LOGIN) {
widget.onSignedIn();
}

} catch (e) {
print('Error: $e');
setState(() {
_isLoading = false;
if (_isIos) {
_errorMessage = e.details;
} else
_errorMessage = 'Incorrect user or password';
});
}
}
}


@override
void initState() {
_errorMessage = "";
_isLoading = false;
super.initState();
}

void _changeFormToSignUp() {
_formKey.currentState.reset();
_errorMessage = "";
setState(() {
_formMode = FormMode.SIGNUP;
});
}

void _changeFormToLogin() {
_formKey.currentState.reset();
_errorMessage = "";
setState(() {
_formMode = FormMode.LOGIN;
});
}

@override
Widget build(BuildContext context) {
_isIos = Theme.of(context).platform == TargetPlatform.iOS;
return new Scaffold(
appBar: new AppBar(
title: new Text('Pet Helper'),
),
body: Stack(
children: <Widget>[
_showBody(),
_showCircularProgress(),
],
));
}

Widget _showCircularProgress(){
if (_isLoading) {
return Center(child: CircularProgressIndicator());
} return Container(height: 0.0, width: 0.0,);

}

void _showVerifyEmailSentDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Verify your account"),
content: new Text("Link to verify account has been sent to your email"),
actions: <Widget>[
new FlatButton(
child: new Text("Dismiss"),
onPressed: () {
_changeFormToLogin();
Navigator.of(context).pop();
},
),
],
);
},
);
}

Widget _showBody(){
return new Container(
padding: EdgeInsets.all(16.0),
child: new Form(
key: _formKey,
child: new ListView(
shrinkWrap: true,
children: <Widget>[
_showLogo(),
_showEmailInput(),
_showPasswordInput(),
_showErrorMessage(),
_showPrimaryButton(),
_showSecondaryButton(),
_googleSignInButton(),

],
),
));
}

Widget _showErrorMessage() {
if (_errorMessage.length > 0 && _errorMessage != null) {
return new Text(
_errorMessage,
style: TextStyle(
fontSize: 13.0,
color: Colors.red,
height: 1.0,
fontWeight: FontWeight.w300),
);
} else {
return new Container(
height: 0.0,
);
}
}

Widget _showLogo() {
return new Hero(
tag: 'hero',
child: Padding(
padding: EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 0.0),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 120.0,
child: Image.asset('assets/babies.png'),
),
),
);
}

Widget _showEmailInput() {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 25.0, 0.0, 0.0),
child: new TextFormField(
maxLines: 1,
keyboardType: TextInputType.emailAddress,
autofocus: false,
decoration: new InputDecoration(
hintText: 'Email',
icon: new Icon(
Icons.mail,
color: Colors.grey,
)),
validator: (String value) {
if (value.isEmpty) {
_isLoading = false;
return 'Email can\'t be empty';
}
else{
return null;
}
},
onSaved: (value) => _email = value.trim(),
),
);
}

Widget _showPasswordInput() {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
child: new TextFormField(
maxLines: 1,
obscureText: true,
autofocus: false,
decoration: new InputDecoration(
hintText: 'Password',
icon: new Icon(
Icons.lock,
color: Colors.grey,
)),
validator: (String value) {
if (value.isEmpty) {
_isLoading = false;
return 'Password can\'t be empty';
}
else{
return null;
}
},
onSaved: (value) => _password = value.trim(),
),
);
}

Widget _showSecondaryButton() {
return new FlatButton(
child: _formMode == FormMode.LOGIN
? new Text('Create an account',
style: new TextStyle(fontSize: 18.0, fontWeight: FontWeight.w300))
: new Text('Have an account? Sign in',
style:
new TextStyle(fontSize: 18.0, fontWeight: FontWeight.w300)),
onPressed: _formMode == FormMode.LOGIN
? _changeFormToSignUp
: _changeFormToLogin,
);
}

Widget _showPrimaryButton() {
return new Padding(
padding: EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0),
child: SizedBox(
height: 40.0,
child: new RaisedButton(
elevation: 5.0,
shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0)),
color: Colors.blue,
child: _formMode == FormMode.LOGIN
? new Text('Login',
style: new TextStyle(fontSize: 20.0, color: Colors.white))
: new Text('Create account',
style: new TextStyle(fontSize: 20.0, color: Colors.white)),
onPressed: _validateAndSubmit,
),
));
}

void submitGoogleLogin() async{
setState(() {
_errorMessage = "";
_isLoading = true;
});
String userId = "";
userId = await widget.auth.signInWithGoogle().whenComplete(() {
widget.onSignedIn();
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return new HomePage();
},
),
);
});
print('Signed in: $userId');
}

Widget _googleSignInButton() {
return OutlineButton(
splashColor: Colors.grey,
onPressed: submitGoogleLogin,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
highlightElevation: 0,
borderSide: BorderSide(color: Colors.grey),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image(image: AssetImage("assets/google_logo.png"), height: 30.0),
Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
'Sign in with Google',
style: TextStyle(
fontSize: 15,
color: Colors.grey,
),
),
)
],
),
),
);
}
}



哦,根页面改变了用户的状态:

import 'package:flutter/material.dart';
import 'login_signup_page.dart';
import 'authentication.dart';
import 'home_page.dart';

class RootPage extends StatefulWidget {
RootPage({this.auth});

final BaseAuth auth;

@override
State<StatefulWidget> createState() => new _RootPageState();
}

enum AuthStatus {
NOT_DETERMINED,
NOT_LOGGED_IN,
LOGGED_IN,
}

class _RootPageState extends State<RootPage> {
AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
String _userId = "";

@override
void initState() {
super.initState();
widget.auth.getCurrentUser().then((user) {
setState(() {
if (user != null) {
_userId = user?.uid;
}
authStatus =
user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
});
});
}

void _onLoggedIn() {
widget.auth.getCurrentUser().then((user){
setState(() {
_userId = user.uid.toString();
});
});
setState(() {
authStatus = AuthStatus.LOGGED_IN;

});
}

void _onSignedOut() {
setState(() {
authStatus = AuthStatus.NOT_LOGGED_IN;
_userId = "";
});
}

Widget _buildWaitingScreen() {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
}

@override
Widget build(BuildContext context) {
switch (authStatus) {
case AuthStatus.NOT_DETERMINED:
return _buildWaitingScreen();
break;
case AuthStatus.NOT_LOGGED_IN:
return new LoginSignUpPage(
auth: widget.auth,
onSignedIn: _onLoggedIn,
);
break;
case AuthStatus.LOGGED_IN:
if (_userId.length > 0 && _userId != null) {
return new HomePage(
userId: _userId,
auth: widget.auth,
onSignedOut: _onSignedOut,
);
} else return _buildWaitingScreen();
break;
default:
return _buildWaitingScreen();
}
}
}


初始化根页面主要.dart

void main() async{
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Pet Helper',
debugShowCheckedModeBanner: false,
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new RootPage(auth: new Auth()));
}
}

最佳答案

abstract class BaseAuth {
Future<String> signIn(String email, String password);

Future<String> signUp(String email, String password);

Future<FirebaseUser> getCurrentUser();

Future<void> sendEmailVerification();

Future<void> signOut();

Future<bool> isEmailVerified();

Future<String> signInWithGoogle();

void signOutGoogle();
}

class Auth implements BaseAuth {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
FirebaseUser user;

Future<String> signIn(String email, String password) async {

user = (await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password)).user;
return user.email;
}

Future<String> signUp(String email, String password) async {
FirebaseUser user = (await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password)).user;
return user.uid;
}

Future<FirebaseUser> getCurrentUser() async {
user = await _firebaseAuth.currentUser();
return user;
}
signOut() async {
print("signed in user: $user");
await _firebaseAuth.signOut();
}

Future<void> sendEmailVerification() async {
FirebaseUser user = await _firebaseAuth.currentUser();
user.sendEmailVerification();
}

Future<bool> isEmailVerified() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user.isEmailVerified;
}

Future<String> signInWithGoogle() async {
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;

final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);

user = (await _firebaseAuth.signInWithCredential(credential)).user;

assert(!user.isAnonymous);
assert(await user.getIdToken() != null);

final FirebaseUser currentUser = await _firebaseAuth.currentUser();
assert(user.uid == currentUser.uid);
return 'signInWithGoogle succeeded: $user';
}
}

final Auth authService = Auth(); // add this to the bottom outside the class

使用全局变量

所以让我解释一下。每次调用 Auth() 时,它都会创建该类的一个新实例。因此,在一种情况下,您可以让用户登录。在另一种情况下,您可以让用户注销。变量将包含不同的变量值。因此,如果您使用与登录用户不同的实例来注销用户,则用户变量将为 null,因此不允许您注销并打印 null。

解决方案

解决方法是全局变量访问一次Auth类。前任。 var authService = Auth();

将变量放在 Auth 类之外,以便可以在任何地方的任何类中访问它

关于firebase - flutter firebase 谷歌注销不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59231866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com