当我在标签之间导航时自动注销问题(Firebase Auth rest API)
Posted
技术标签:
【中文标题】当我在标签之间导航时自动注销问题(Firebase Auth rest API)【英文标题】:problem automatic log off when I navigate between tabs (Firebase Auth rest API) 【发布时间】:2021-11-13 15:26:02 【问题描述】:您好,我正在构建一个应用程序,我正在使用 Firebase Auth rest API 进行身份验证,但问题是当我在标签之间导航时,我的应用程序会自动注销,我不知道是令牌过期问题还是其他问题那么有人可以帮忙吗?
这是我的身份验证部分,它在我的提供程序包中
class Auth with ChangeNotifier
String _token;
String _userId;
bool get isAuth
return token != null;
String get token
return _token;
String get userId
return _userId;
Future<void> signup(String email, String password) async
final url = Uri.parse(
'https://...myurl...'
);
try
final response = await http.post(url,body: json.encode(
'email': email,
'password':password,
'returnSecureToken': true,
,), );
final responseData = json.decode(response.body);
if(responseData['error'] != null)
throw Exception();
_token = responseData['idToken'];
_userId = responseData['localId'];
notifyListeners();
catch (error)
throw error;
Future<void> login(String email, String password) async
final url = Uri.parse( 'https://...myurl...' );
try
final response = await http.post(
url,
body: json.encode(
'email': email,
'password':password,
'returnSecureToken': true,
,),);
catch (error)
throw error;
这是 Ath 屏幕:
enum AuthMode Signup, Login
class AuthScreen extends StatelessWidget
static const routeName = '/auth';
@override
Widget build(BuildContext context)
final deviceSize = MediaQuery.of(context).size;
bool _isLoading= false;
return Scaffold(
backgroundColor: Colors.pinkAccent[100],
body: SizedBox(
height: double.infinity,
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.all(8),
margin: EdgeInsets.all(8),
child: Expanded(
child:
SizedBox(
height: 280,
),
),
),
SingleChildScrollView(
child: Container(
height: deviceSize.height,
width: deviceSize.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 60,
child: LogoBekery(
color1:Colors.white,
color2:Colors.white,
color3:Colors.white,
),
),
SizedBox(
child: ImageSlideshow(
isLoop: true,
width: double.infinity,
height: 250,
initialPage: 0,
indicatorColor: Colors.pink,
indicatorBackgroundColor: Colors.grey,
children: [
Image.asset(
'assets/images/logoA.png',
fit: BoxFit.fill,
),
Image.asset(
'assets/images/logoB.png',
fit: BoxFit.fill,
),
Image.asset(
'assets/images/logoC.png',
fit: BoxFit.fill,
),
Image.asset(
'assets/images/logoD.png',
fit: BoxFit.fill,
),
],
onPageChanged: (value)
// print('Page changed: $value');
,
autoPlayInterval: 3000,
),
),
Flexible(
flex: deviceSize.width > 600 ? 2 : 1,
child: AuthCard(),
),
],
),
),
),
],
),
),
);
void _submitAuthForm(
String email,
String password,
String username,
bool isLogin,
BuildContext ctx,
)
async
UserCredential authResult;
class AuthCard extends StatefulWidget
const AuthCard(
Key key,
) : super(key: key);
@override
_AuthCardState createState() => _AuthCardState();
class _AuthCardState extends State<AuthCard>
final GlobalKey<FormState> _formKey = GlobalKey();
AuthMode _authMode = AuthMode.Login;
Map<String, String> _authData =
'email': '',
'password': '',
;
var _isLoading = false;
final _passwordController = TextEditingController();
Future<void> _submit() async
if (!_formKey.currentState.validate())
// Invalid!
return;
_formKey.currentState.save();
setState(()
_isLoading = true;
);
try
if (_authMode == AuthMode.Login)
await Provider.of<Auth>(context, listen: false).login(
_authData['email'] ,
_authData['password'] );
else
await Provider.of<Auth>(context, listen: false).signup(
_authData['email'] ,
_authData['password'] );
Navigator.of(context).pushReplacementNamed(ProductOverviewScreen.routeName);
on Exception catch (error)
var errorMsg = 'Authentification Failed!';
catch (error)
var errorMsg = 'Could not authentificate! please try later...';
setState(()
_isLoading = false;
);
void _switchAuthMode()
if (_authMode == AuthMode.Login)
setState(()
_authMode = AuthMode.Signup;
);
else
setState(()
_authMode = AuthMode.Login;
);
@override
Widget build(BuildContext context)
final deviceSize = MediaQuery.of(context).size;
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 8.0,
child: Container(
height: _authMode == AuthMode.Signup ? 320 : 260,
constraints:
BoxConstraints(minHeight: _authMode == AuthMode.Signup ? 150 : 260),
width: deviceSize.width * 0.8,
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: 'E-Mail'),
keyboardType: TextInputType.emailAddress,
validator: (value)
if (!RegExp(r'\S+@\S+\.\S+').hasMatch(value))
return 'Invalid email!';
return null;
return null;
,
onSaved: (value)
_authData['email'] = value;
,
),
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
controller: _passwordController,
validator: (value)
if (value.isEmpty || value.length < 5)
return 'Password is too short!';
,
onSaved: (value)
_authData['password'] = value;
,
),
if (_authMode == AuthMode.Signup)
TextFormField(
enabled: _authMode == AuthMode.Signup,
decoration: InputDecoration(labelText: 'Confirm Password'),
obscureText: true,
validator: _authMode == AuthMode.Signup
? (value)
if (value != _passwordController.text)
return 'Passwords do not match!';
: null,
),
SizedBox(
height: 20,
),
if (_isLoading)
CircularProgressIndicator()
else
RaisedButton(
child:
Text(_authMode == AuthMode.Login ? 'LOGIN' : 'SIGN UP'),
onPressed: _submit,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
padding:
EdgeInsets.symmetric(horizontal: 30.0, vertical: 8.0),
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).primaryTextTheme.button.color,
),
FlatButton(
child: Text(
'$_authMode == AuthMode.Login ? 'SIGNUP' : 'LOGIN''),
onPressed: _switchAuthMode,
padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 4),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Theme.of(context).primaryColor,
),
],
),
),
),
),
);
【问题讨论】:
身份验证状态会自动保持,因此您检测当前用户的方式可能存在一些问题。但是如果没有看到minimal code that reproduces the problem,就很难提供帮助。 我已经添加了我的代码的 auth 部分 如何检查用户是否登录? @PeterO。短期内是使用这个 mth try if (_authMode == AuthMode.Login) await Provider.of(context, listen: false).login( _authData['email'] , _authData['password'] ) ; else await Provider.of(context, listen: false).signup( _authData['email'] , _authData['password'] ); Navigator.of(context).pushReplacementNamed(ProductOverviewScreen.routeName); on Exception catch (error) var errorMsg = 'Failed!'; catch (error) var errorMsg = 'error'; 没找到你吗? 【参考方案1】:您的_token
和_userId
仅在注册后设置。登录后不设置。因此token可能为null,isAuth
会返回false。
我认为你应该在登录功能之后设置_token
和_userId
的值。
Future<void> login(String email, String password) async
final url = Uri.parse('https://...myurl...');
try
final response = await http.post(
url,
body: json.encode(
'email': email,
'password': password,
'returnSecureToken': true,
,
),
);
// added from here
final responseData = json.decode(response.body);
if (responseData['error'] != null)
throw Exception();
_token = responseData['idToken'];
_userId = responseData['localId'];
// to here.
catch (error)
throw error;
【讨论】:
我应该从注册中删除它还是在登录时添加它? 添加到登录。我分享的代码就是一个例子。试试看。 我试过了,但没用 我不确定,但我认为我有一个带有我的令牌的 pb,它已过期,所以 p 可能是来自 firebase 的表单,但不知道如何处理以上是关于当我在标签之间导航时自动注销问题(Firebase Auth rest API)的主要内容,如果未能解决你的问题,请参考以下文章
当我在firebase上删除他的帐户时如何从应用程序中注销用户?