I am new to flutter, I am creating my app and in the auth screen when I try to signup a new user and press the signup button I am getting a message(an error occurred!) and I a don't know why and it is not creating the new user nor add him to the firebase authentication and when I press signup these are the tow messages that come on the debug console:I/ViewRootImpl@875f842MainActivity: ViewPostIme pointer 0 I/ViewRootImpl@875f842MainActivity: ViewPostIme pointer 1 so what can I do? this is the auth file:
import 'dart:math';
import 'package:app1/http_exception.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
class Auth with ChangeNotifier {
String _token;
DateTime _expirydate;
String _userid;
Timer authtimer;
bool get isauth {
return token != null;
}
String get token {
if (_expirydate != null &&
_expirydate.isAfter(DateTime.now()) &&
_token != null) {
return token;
}
return null;
}
String get userid {
return userid;
}
Future<void> authenticate(
String email, String password, String urlseg) async {
final url =
'https://identitytoolkit.googleapis.com/v1/accounts:$urlseg?Key=AIzaSyC3csifqiu5s28nskttUnxz1UMz-sdfkjlksfmlksd';
try {
final res = await http.post(url,
body: jsonEncode({
'email': email,
'password': password,
'returnSecureToken': true
}));
final responsedata = json.decode(res.body);
if (responsedata['error'] != null) {
httpexception(responsedata['error']['message']);
}
_token = responsedata['idToken'];
_userid = responsedata['localId'];
_expirydate = DateTime.now()
.add(Duration(seconds: int.parse(responsedata['expiresIn'])));
_autologout();
notifyListeners();
final prefs = await SharedPreferences.getInstance();
String userData = json.encode({
'token': _token,
'userId': _userid,
'expiryDate': _expirydate.toIso8601String()
});
prefs.setString('userData', userData);
} catch (e) {
throw e;
}
}
Future<void> signup(String email, String password) async {
return authenticate(email, password, "signup");
}
Future<void> login(String email, String password) async {
return authenticate(email, password, "signinWithPassword");
}
Future<bool> tryautologin() async {
final prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey('userData')) return false;
final Map<String, Object> extracteddata =
json.decode(prefs.getString('userData')) as Map<String, Object>;
final expirydate = DateTime.parse(extracteddata['expiryDate']);
if (expirydate.isBefore(DateTime.now())) return false;
_token = extracteddata['token'];
_userid = extracteddata['userData'];
_expirydate = extracteddata['expiryDate'];
notifyListeners();
_autologout();
return true;
}
Future<void> logout() async {
_token = null;
_userid = null;
_expirydate = null;
if (authtimer != null) {
authtimer.cancel();
authtimer = null;
}
notifyListeners();
final prefs = await SharedPreferences.getInstance();
prefs.clear();
}
void _autologout() {
if (authtimer != null) {
authtimer.cancel();
authtimer = null;
}
final timetoexpiry = _expirydate.difference(DateTime.now()).inSeconds;
authtimer = Timer(Duration(seconds: timetoexpiry), logout);
}
}
and that is the authscreen file:
import 'dart:math';
import 'package:app1/http_exception.dart';
import 'package:app1/providers/auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../http_exception.dart';
class Authscreen extends StatelessWidget {
static const routname = '/auth';
@override
Widget build(BuildContext context) {
final devicesize = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromRGBO(215, 117, 255, 1).withOpacity(0.5),
Color.fromRGBO(215, 188, 117, 1).withOpacity(0.9),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0, 1],
)),
),
SingleChildScrollView(
child: Container(
height: devicesize.height,
width: devicesize.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Container(
margin: EdgeInsets.only(bottom: 20),
padding: EdgeInsets.symmetric(
vertical: 8,
horizontal: 94,
),
transform: Matrix4.rotationZ(-8 * pi / 180)
..translate(-10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.deepOrange.shade900,
boxShadow: [
BoxShadow(
blurRadius: 8,
color: Colors.black26,
offset: Offset(0, 2)),
],
),
child: Text(
'my shop',
style: TextStyle(
color:
Theme.of(context).accentTextTheme.headline6.color,
fontSize: 50,
fontFamily: 'Anton',
),
),
),
),
Flexible(
child: AuthCard(), flex: devicesize.width > 600 ? 2 : 1)
],
),
),
)
],
),
);
}
}
class AuthCard extends StatefulWidget {
@override
AuthCardState createState() => AuthCardState();
}
enum Authmode { Login, Signup }
class AuthCardState extends State<AuthCard>
with SingleTickerProviderStateMixin {
final GlobalKey<FormState> formkey = GlobalKey();
Authmode authmode = Authmode.Login;
Map<String, String> authdata = {
'email': '',
'password': '',
};
var isloading = false;
final passwordcontroller = TextEditingController();
AnimationController controller;
Animation<Offset> slideanimation;
Animation<double> opacityanimation;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
slideanimation = Tween<Offset>(begin: Offset(0, -0.15), end: Offset(0, 0))
.animate(
CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn));
opacityanimation = Tween<double>(begin: 0.0, end: 1.0)
.animate(CurvedAnimation(parent: controller, curve: Curves.easeIn));
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
Future<void> submit() async {
if (!formkey.currentState.validate()) {
return;
}
FocusScope.of(context).unfocus();
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']);
}
} on httpexception catch (error) {
var errormessage = 'Authentication failed';
if (error.toString().contains('EMAIL_EXISTS')) {
errormessage = 'This email is already in use';
} else if (error.toString().contains('EMAIL_NOT_FOUND')) {
errormessage = 'could not find a user with that email';
} else if (error.toString().contains('INVALID_EMAIL')) {
errormessage = 'this is not a valid email address';
} else if (error.toString().contains('WEAK_PASSWORD')) {
errormessage = 'This password is to short';
} else if (error.toString().contains('INVALID_PASSWORD')) {
errormessage = 'invalid password';
}
showerrordialog(errormessage);
} catch (error) {
const errormessage = 'please try again later';
showerrordialog(errormessage);
}
setState(() {
isloading = false;
});
}
void switchauthmode() {
if (authmode == Authmode.Login) {
setState(() {
authmode = Authmode.Signup;
});
controller.forward();
} else {
setState(() {
authmode = Authmode.Login;
controller.reverse();
});
}
}
void showerrordialog(String message) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('an error occured!'),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('okay!'))
],
));
}
@override
Widget build(BuildContext context) {
final devicesize = MediaQuery.of(context).size;
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 8.0,
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeIn,
height: authmode == Authmode.Signup ? 320 : 260,
constraints: BoxConstraints(
minHeight: authmode == Authmode.Signup ? 320 : 260,
),
width: devicesize.width * 0.75,
padding: EdgeInsets.all(16),
child: Form(
key: formkey,
child: SingleChildScrollView(
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: 'E-mail'),
keyboardType: TextInputType.emailAddress,
validator: (val) {
if (val.isEmpty || !val.contains('@')) {
return 'invalid email';
}
return null;
},
onSaved: (val) {
authdata['email'] = (val);
},
),
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
controller: passwordcontroller,
validator: (val) {
if (val.isEmpty || val.length < 7) {
return 'invalid password';
}
return null;
},
onSaved: (val) {
authdata['password'] = (val);
},
),
AnimatedContainer(
constraints: BoxConstraints(
minHeight: authmode == Authmode.Signup ? 60 : 0,
maxHeight: authmode == Authmode.Signup ? 120 : 0,
),
duration: Duration(milliseconds: 300),
curve: Curves.easeIn,
child: FadeTransition(
opacity: opacityanimation,
child: SlideTransition(
position: slideanimation,
child: TextFormField(
enabled: authmode == Authmode.Signup,
decoration:
InputDecoration(labelText: 'Confirm Password'),
obscureText: true,
validator: authmode == Authmode.Signup
? (val) {
if (val != passwordcontroller.text) {
return 'Password do not match';
}
return null;
}
: null,
),
),
),
),
SizedBox(
height: 20,
),
if (isloading) CircularProgressIndicator(),
ElevatedButtonTheme(
data: ElevatedButtonThemeData(
style: ButtonStyle(
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)),
),
padding: MaterialStateProperty.all(
EdgeInsets.symmetric(vertical: 8, horizontal: 30)),
foregroundColor: MaterialStateProperty.all(
Theme.of(context).primaryTextTheme.headline6.color),
)),
child: ElevatedButton(
child:
Text(authmode == Authmode.Login ? 'LOGIN' : 'SIGNUP'),
onPressed: submit,
),
),
TextButtonTheme(
data: TextButtonThemeData(
style: ButtonStyle(
padding: MaterialStateProperty.all(
EdgeInsets.symmetric(
vertical: 4, horizontal: 30)),
foregroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColor),
),
),
child: TextButton(
onPressed: switchauthmode,
child: Text(
'${authmode == Authmode.Login ? 'SIGNUP' : 'LOGIN'} INSTEAD'),
))
],
),
),
)),
);
}
}