I am working with Firebase authentication and lately was not able to do anything because of the following error. When I enter the user's credentials, it gets authenticated on the Firebase console, but my app's screen does not change. What's more, the following error appears in debug console.
2 I/System.out(26261): (HTTPLog)-Static: isSBSettingEnabled false
I/SurfaceControl(26261): nativeRelease nativeObject
s[-5476376676702711408] I/SurfaceControl(26261): nativeRelease
nativeObject e[-5476376676702711408] W/System (26261): Ignoring
header X-Firebase-Locale because its value was null. 2
I/System.out(26261): (HTTPLog)-Static: isSBSettingEnabled false
void authUser(
String email, String password, String conPassword, bool isLogin) async {
UserCredential authResult;
setState(() {
isLoading = true;
});
FocusScope.of(context).unfocus();
try {
if (password != conPassword && isLogin == false) {
showDialog(
context: context,
builder: (_) => const AlertDialog(
title: Text('Passwords don\'t match'),
content: Text('Please check if your passwords match'),
),
);
}
if (isLogin == false) {
authResult = await firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: password,
);
} else {
authResult = await firebaseAuth.signInWithEmailAndPassword(
email: email,
password: password,
);
}
setState(() {
isLoading = false;
});
} catch (e) {
rethrow;
}
}
...
TextFormField(
key: const ValueKey('email'),
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
label: Text('Email adress'),
),
onSaved: (newValue) {
email = newValue!;
FocusScope.of(context).requestFocus(_passwordNode);
},
),
TextFormField(
key: const ValueKey('password'),
focusNode: _passwordNode,
obscureText: true,
onSaved: (newValue) {
password = newValue!;
FocusScope.of(context).requestFocus(_conPasswordNode);
},
decoration: const InputDecoration(
label: Text('Password'),
),
),
if (isLogin == false)
TextFormField(
key: const ValueKey('conPassword'),
focusNode: _conPasswordNode,
obscureText: true,
decoration: const InputDecoration(
label: Text('Confirm password'),
),
onSaved: (newValue) {
conPassword = newValue!;
},
),
Expanded(
child: Container(),
),
widget.isLoading == true
? const Center(
child: CircularProgressIndicator(),
)
: ButtonBar(
alignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
isLogin = !isLogin;
});
},
child: Text(isLogin == true ? 'SignUp' : 'Login'),
),
ElevatedButton(
onPressed: _trySubmit,
child: const Text('Done'),
),
],
),
...
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: Firebase.initializeApp(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (ctx) => RecipeProvider(),
),
],
child: MaterialApp ...
home: StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasData) {
return AllRecipesScreen();
}
return AuthScreen();
}),
routes: {
AllRecipesScreen.routeName: (ctx) => AllRecipesScreen(),
RecipeDetailScreen.routeName: (ctx) => RecipeDetailScreen(),
AddRecipeScreen.routeName: (ctx) => AddRecipeScreen(),
AuthScreen.routeName: (ctx) => AuthScreen(),
},
),
);
});
}
}
try changing the targetedSdk to 27, hope this helps.
The code seems to be quite incomplete to conclude anything out of it.
And as much as I know the logs that you have provided are not errors , it is just that way and are printed every-time. I don't think your main issue seems to be firebase authentication. It may be an issue of navigation(or a wrapper if you're using one).
Related
Flutter Error: Null check operator used on a null value in a StreamBuilder
no matter what i do i keep getting this error instead of the user data that i want,
in the database.dart i didn't put any ! or ? so i guess the problem's from this file, but i have no clue how to fix it.
i also tried all the commands i found on google but none of them works
class SettingsForm extends StatefulWidget {
const SettingsForm({Key? key}) : super(key: key);
#override
_SettingsFormState createState() => _SettingsFormState();
}
class _SettingsFormState extends State<SettingsForm> {
final _formKey = GlobalKey<FormState>();
final List<String> sugars = ['0','1','2','3','4'];
String?_currentName ;
String?_currentSugars ;
dynamic _currentStrength =1;
#override
Widget build(BuildContext context) {
final user = Provider.of<myUser?>(context);
return StreamBuilder<myUserData?>(
stream: DatabaseService(uid: user!.uid).userData,
builder: (context, snapshot) {
if(snapshot.hasData) {
myUserData? usdata = snapshot.data;
return Form(
key:_formKey,
child: Column(
children: [
Text('Update your brew settings.',
style: TextStyle(fontSize:18.0),),
SizedBox(height: 20,),
TextFormField(
initialValue: usdata?.name,
decoration: textInputDecoration.copyWith(hintText: ' name'),
validator: (val) => val!.isEmpty ? 'Please enter a name' : null,
onChanged: (val) {
setState(() => _currentName = val);
},
),
SizedBox(height: 20.0,),
//dropdown
DropdownButtonFormField<String>(
value: usdata?.sugars,
items: sugars.map((sugar){
return DropdownMenuItem(
value: sugar,
child: Text(' $sugar sugars')
);
}).toList(),
onChanged: (val) => setState(() => _currentSugars = val.toString()),
),
SizedBox(height:20 ),
//slider
Slider(
value: (_currentStrength ?? usdata?.strength).toDouble(),
activeColor: Colors.brown[_currentStrength ?? usdata?.strength],
inactiveColor: Colors.brown[_currentStrength ?? usdata?.strength],
min:100,
max:900,
divisions: 8,
onChanged: (val) => setState(() {
_currentStrength = val.round();
}),
),
RaisedButton(
color:Colors.pink[400],
child: Text('Update',
style: TextStyle(color:Colors.white),),
onPressed: () async {
print(_currentName);
print(_currentSugars);
print(_currentStrength);
})
],
),
);
}
else {
myUserData usdata = snapshot.data!;
print(usdata.name);
print(usdata.sugars);
print(usdata.strength);
return Container();
}
}
);
}
}
Here is a simplification of your code:
builder: (context, snapshot) {
if(snapshot.hasData) {
...
} else {
myUserData usdata = snapshot.data!;
print(usdata.name);
print(usdata.sugars);
print(usdata.strength);
return Container();
}
},
The code in your else statement will only run if snapshot.hasData is false, which means that snapshot.data is null, giving you an error when you try to read it.
I'm using package search_page
I want to show user name when searching their name like this example
Here is my Firestore, I have user named Test User One and Test User Two
Here is my code for FloatingActionButton( )
FloatingActionButton(
onPressed: () => showSearch(
context: context,
delegate: ChatSearch(),
),
child: Icon(Icons.chat),
),
Here is my code for ChatSearch( )
class ChatSearch extends SearchDelegate {
FirebaseFirestore _fires = FirebaseFirestore.instance;
Future<QuerySnapshot> getUserInfo() async {
return await _fires.collection("Students").where("displayName", isEqualTo: query).get();
}
...
#override
Widget buildResults(BuildContext context) {
return Column(
children: [
FutureBuilder(
future: getUserInfo(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('No user found.');
}
else if (snapshot.connectionState == ConnectionState.waiting) {
return Text('Loading ...');
}
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.docs.length,
itemBuilder: (BuildContext context, int index) {
var result = snapshot.data.docs[index];
return ListTile(
title: Text(result["displayName"]),
subtitle: Text(result["society"]),
leading: CircleAvatar(backgroundImage: NetworkImage(result["photoUrl"]),),
);
},
);
}),
],
);
}
}
Here is my screenshot
How can I get the query (all user name matched with search) instead of isEqualTo?
For example, when I search Test User, it will appear Test User One and Test User Two
Really appreciate if anyone can help me or provide me some direction. Thanks.
It's easy no need to use the plugin here is the code
//it's the code to search for user for name
static Future<QuerySnapshot> getUserInfo(String name) {
Future<QuerySnapshot> users =
usersRef.where('name', isGreaterThanOrEqualTo: name).getDocuments();
return users;
}
and this are some values
TextEditingController _searchController = TextEditingController();
Future<QuerySnapshot> _users;
String _searchText = '';
and it's the search ui code
#override
Widget build(BuildContext context) {
String _currentUserId = Provider.of<UserData>(context).currentUserId;
void _clearSearch() {
WidgetsBinding.instance
.addPostFrameCallback((_) => _searchController.clear());
setState(() {
_users = null;
_searchText = '';
});
}
return Scaffold(
appBar: AppBar(
title: TextField(
controller: _searchController,
decoration: InputDecoration(
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(vertical: 15.0),
border: InputBorder.none,
hintText: 'Search for a user...',
prefixIcon: Icon(
Icons.search,
color: Theme.of(context).accentColor.withOpacity(0.6),
size: 30.0,
),
suffixIcon: _searchText.trim().isEmpty
? null
: IconButton(
color: Theme.of(context).accentColor.withOpacity(0.6),
icon: Icon(Icons.clear),
onPressed: _clearSearch,
),
// filled: true,
),
onChanged: (value) {
setState(() {
_searchText = value;
});
},
onSubmitted: (input) {
if (input.trim().isNotEmpty) {
setState(() {
_users = DatabaseService.searchUsers(input);
});
}
},
),
),
body: _users == null
? Center(child: Text('Search for users'))
: FutureBuilder(
future: _users,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.data.documents.length == 0) {
return Center(
child: Text('No Users found! Please try again.'),
);
}
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
//User user = User.fromDoc(snapshot.data.documents[index]);
// Prevent current user to send messages to himself
return null;
// (widget.searchFrom != SearchFrom.homeScreen &&
// user.id == _currentUserId)
// ? SizedBox.shrink()
// : _buildUserTile(user);
});
},
),
);
}
and this is the user tile
ListTile _buildUserTile(User user) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.grey,
radius: 20.0,
backgroundImage: user.profileImageUrl.isEmpty
? AssetImage(placeHolderImageRef)
: CachedNetworkImageProvider(user.profileImageUrl),
),
title: Row(
children: [Text(user.name)],
),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ProfileScreen()
),
)
);
}
Hope it works, if something is missing then tell me.
I've followed a tutorial regarding 'Flutter Firebase Authentication.
I faced many issues due to it being in an old version of firebase, but I migrated and fixed all problems related to the null safety and others. It showed 0 problems/errors.
But on execution, the following error message appears multiple times.
D/libGLESv2(15242): STS_GLApi : DTS is not allowed for Package : com.example.realone
W/libc (15242): It seems that pthread_join() is not invoked or PTHREAD_ATTR_FLAG_DETACHED is not set.
W/libc (15242): pthread tid : 15281
W/libc (15242): pthread start_routine: 0xdeeecce
In the phone, it gives a place where we can write the email and password but when we click on the sign in button it doesn't do anything.
my Sign_in code :
class _LoginPageState extends State<LoginPage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late String _email, _password;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
validator: (input) {
if (input!.isEmpty) {
return 'Provide an email';
}
},
decoration: InputDecoration(labelText: 'Email'),
onSaved: (input) => _email = input!,
),
TextFormField(
validator: (input) {
if (input!.length < 6) {
return 'Longer password please';
}
},
decoration: InputDecoration(labelText: 'Password'),
onSaved: (input) => _password = input!,
obscureText: true,
),
ElevatedButton(
onPressed: signIn,
child: Text('Sign in'),
),
],
)),
);
}
void signIn() async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
try {
User? user = (await FirebaseAuth.instance
.signInWithEmailAndPassword(email: _email, password: _password))
.user;
// print(user);
Navigator.push(context,
MaterialPageRoute(builder: (context) => Home(user: user!)));
} catch (e) {
print(e);
}
}
}
}
my home code (the page where the app goes after signing in)
lass Home extends StatelessWidget {
const Home({Key? key, required this.user}) : super(key: key);
final User user;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home ${user.email}'),
),
body: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(user.uid)
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
return checkRole(snapshot.data!);
}
return LinearProgressIndicator();
},
),
);
}
Center checkRole(DocumentSnapshot snapshot) {
if (snapshot.data() == null) {
return Center(
child: Text('no data set in the userId document in firestore'),
);
}
if ((snapshot.data() as dynamic)['role'] == 'admin') {
return adminPage(snapshot);
} else {
return userPage(snapshot);
}
}
Center adminPage(DocumentSnapshot snapshot) {
return Center(
child: Text(
'${(snapshot.data() as dynamic)['role']} ${(snapshot.data() as dynamic)['name']}'));
}
Center userPage(DocumentSnapshot snapshot) {
return Center(child: Text((snapshot.data() as dynamic)['name']));
}
}
I have two other files main.dart and signUp.dart
Would be glad to know the issues in code.
Thanks in advance.
Hy Guys I have connected flutter to my firebase project and used AUTH feature in Firebase but what I would do is to show an error message when a wrong password or Email user is wrong.
this is my code:
Widget submitButton (){
return Container(
child: SizedBox(
width: 220,
height: 40,
child: MaterialButton(
elevation: 5,
onPressed: () async {
setState(() {
showProgress = true;
});
try {
final newUser = await _auth.signInWithEmailAndPassword(email: email, password: password);
print(newUser.toString());
if (newUser != null) {
Navigator.push(context, PageTransition(
type: PageTransitionType.fade,
child: WelcomeScreen(),
));
setState(() {
showProgress = false;
});
}
} catch (e) {}
},
child: Text('Accedi',style: TextStyle(color: Colors.black),),
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Colors.black12,width: 1)),
),
),
);
}
First you need to catch the error, you can do that by using catchError():
final newUser = await _auth.signInWithEmailAndPassword(email: email, password: password)
.catchError((err) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Error"),
content: Text(err.message),
actions: [
FlatButton(
child: Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
});
Then the showDialog will have err.message which will contain the error received from Firebase Authentication.
You have two options:
1.Use an alert dialog
void _showAlertDialog(String message) async {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(message),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
full example
Use errorText property in InputDecoration
TextField(
decoration: InputDecoration(
errorText: this.errorText,
),
)
full example
You can use a Form() with TextFormField()
Something like this:
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
key: ValueKey('email'),
validator: (value) {
if (value.isEmpty || !value.contains('#'))
return 'Please enter a valid Email address';
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(labelText: 'Email address'),
onSaved: (value) {
_userEmail = value;
},
),
It's just a dummy, but as you see there's some validation code in the validator attribute.
So what validator does is, if you return null everything is well and good, but if something is wrong, just return the String and it'll be shown below the text form field as an error message.
And to validate you can call a method like this to activate the method while form submission
void _trySubmit() {
final bool isValid = _formKey.currentState.validate();
FocusScope.of(context).unfocus();
if (isValid) {
_formKey.currentState.save();
widget.submitFn(
_userEmail.trim(),
_userName.trim(),
_userPassword.trim(),
_isLogin,
context,
);
}}
The method for getting isValid will invoke validation function of all TextFormFields, if all of them are okay, it'll return true else it'll return false.
All the _name are used to store the values in state variables using the onSaved attribute.
Let me know if you have anymore doubts.
Hope this helps✌
I'm having troubles with creating users in my app, I get an error that says I don't have sufficient permissions even though I should have permission. My security rules are allowing users to be created so I don't really understand why I am getting this error. What's even more strange is that it works on my mates computer, he can create users (with the exact same userdetails). He is on a pc and I on a mac not sure if that matters?
The error I get is the following:
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: PlatformException(Error 7, FIRFirestoreErrorDomain, Missing or insufficient permissions.)
Our security rules are:
service cloud.firestore {
//match /databases/{database}/documents {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth != null;
}
match /Users/{userId} {
allow update: if request.auth.uid == userId;
}
match /Users/{document=**} {
allow create;
}
match /Recipes/{document=**} {
allow create: if request.auth != null;
allow update, delete: if request.resource.data.userId == request.auth.uid;
}
match /Recipes/{document=**}/newRatings {
allow create, update: if request.auth != null;
}
}
} ```
Our code for registering users is:
´´´ import 'package:cibus/pages/loginScreens/username_screen.dart';
import 'package:cibus/pages/loginScreens/verify_screen.dart';
import 'package:cibus/services/colors.dart';
import 'package:flutter/material.dart';
import 'package:cibus/services/login/auth.dart';
import 'package:cibus/services/constants.dart';
import 'package:cibus/pages/loginScreens/e-sign_in_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_user_stream/firebase_user_stream.dart';
import 'package:cibus/services/my_page_view.dart';
import 'package:provider/provider.dart';
import 'package:cibus/services/login/user.dart';
import 'package:cibus/services/database.dart';
import 'package:cibus/pages/loading_screen.dart';
const registerButtonColor = kTurquoise;
const formSizedBox = SizedBox(height: 20.0);
const EdgeInsets formPadding =
EdgeInsets.symmetric(vertical: 10.0, horizontal: 50.0);
const TextStyle textStyleErrorMessage =
TextStyle(color: Colors.red, fontSize: 14.0);
const TextStyle textStyleRegisterButton = TextStyle(color: Colors.white);
OutlineInputBorder textInputBorder = OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
);
class RegisterScreen extends StatefulWidget {
final Function toggleView;
RegisterScreen({this.toggleView});
#override
_RegisterScreenState createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
bool loading = false;
bool isVerified = false;
//final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
//text field state
String email = '';
String password = '';
String error = '';
String name = '';
String description = '';
String _currentUsername;
int age = 0;
int dropdownValue = null;
final TextEditingController _pass = TextEditingController();
final TextEditingController _confirmPass = TextEditingController();
#override
Widget build(BuildContext context) {
return loading
? LoadingScreen()
: Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: AppBar(
backgroundColor: Theme.of(context).backgroundColor,
elevation: 0.0,
title: Text('Sign up to Cibus', style: TextStyle(color: kCoral)),
actions: <Widget>[
FlatButton.icon(
icon: Icon(Icons.person, color: kCoral),
label: Text('Sign in', style: TextStyle(color: kCoral)),
onPressed: () {
//widget.toggleView();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) {
return EmailSignIn();
},
),
);
},
),
],
),
body: Padding(
padding: formPadding,
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(children: <Widget>[
formSizedBox,
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
enabledBorder: textInputBorder,
border: textInputBorder,
labelText: 'Email',
),
validator: (val) =>
val.isEmpty ? 'Enter an email' : null,
onChanged: (val) {
setState(() => email = val);
},
),
formSizedBox,
TextFormField(
decoration: InputDecoration(
enabledBorder: textInputBorder,
border: textInputBorder,
labelText: 'Password',
),
obscureText: true,
controller: _pass,
validator: (String val) {
Pattern pattern =
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$';
RegExp regex = new RegExp(pattern);
print(val);
if (val.isEmpty) {
return 'Please enter password';
} else if (val.length < 8) {
return 'Minimum 8 characters required';
} else if (!val.contains(RegExp(r'[A-Z]'))) {
return 'One upper case letter required.';
} else if (!val.contains(RegExp(r'[a-z]'))) {
return 'One lower case letter required.';
} else if (!val.contains(RegExp(r'[0-9]'))) {
return 'One digit required.';
} else if (!val
.contains(RegExp(r'[!##$%^&*(),.?":{}|<>]'))) {
return 'One special character required.';
} /*
else {
if (!regex.hasMatch(val))
return 'Enter valid password: \n'
'Password must contain at least one upper case letter. \n'
'Password must contain at least one lower case letter. \n'
'Password must contain at least one digit. \n'
'Password must contain at least one special character.'; */
else
return null;
//}
},
onChanged: (val) {
setState(() => password = val);
},
),
formSizedBox,
TextFormField(
decoration: InputDecoration(
enabledBorder: textInputBorder,
border: textInputBorder,
labelText: ' Re-enter Password',
),
obscureText: true,
controller: _confirmPass,
validator: (String val) {
if (val.isEmpty)
return 'Re-enter password field is empty';
if (val != _pass.text)
return 'passwords do not match';
return null;
},
onChanged: (val) {
setState(() => password = val);
},
),
formSizedBox,
TextFormField(
decoration: InputDecoration(
enabledBorder: textInputBorder,
border: textInputBorder,
labelText: 'Name',
),
validator: (val) =>
val.isEmpty ? 'Enter your name' : null,
onChanged: (val) {
setState(() => name = val);
},
),
formSizedBox,
TextFormField(
decoration: InputDecoration(
enabledBorder: textInputBorder,
border: textInputBorder,
labelText: 'Description',
),
minLines: 5,
maxLines: 10,
validator: (val) =>
val.isEmpty ? 'Enter your description' : null,
onChanged: (val) {
setState(() => description = val);
},
),
formSizedBox,
TextFormField(
maxLength: 20,
decoration: InputDecoration(
enabledBorder: textInputBorder,
border: textInputBorder,
labelText: 'Username',
),
validator: (val) {
if (val.length < 3)
return 'Username must be more than 2 characters';
/*else if (checkUsername == false)
return 'Username is allready taken';*/
return null;
},
onChanged: (val) {
setState(() {
_currentUsername = val;
print(_currentUsername);
});
}),
formSizedBox,
RaisedButton(
color: kCoral,
child: Text('Register', style: textStyleRegisterButton),
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
bool isUsernameFree = await DatabaseService()
.isUsernameTaken(username: _currentUsername);
print(' checkUsername: $isUsernameFree');
if (!isUsernameFree) {
dynamic result =
await _auth.registerWithEmailAndPassword(
email, password, name, description, age);
if (result == null) {
setState(() {
error = 'Email is already registered';
_verificationEmailDialog();
});
} else {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) {
return VerifyScreen();
},
),
);
}
} else {
setState(() {
error = 'Username is already taken';
});
_usernameDialog();
}
}
},
),
Text(
error,
style: textStyleErrorMessage,
),
])),
),
));
}
Future<void> _usernameDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Username is already taken'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Unfortunately it seems like your username is allready taken. Please try another one'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Aight bruh'),
onPressed: () {
setState(() {
loading = false;
});
Navigator.of(context)
.pop(); //TODO: When popping try to keep text in forms
},
),
],
);
},
);
}
Future<void> _verificationEmailDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Email is already in use'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Unfortunately it seems like the email is already in use. Please try another one'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Aight bruh'),
onPressed: () {
setState(() {
loading = false;
});
Navigator.of(context)
.pop(); //TODO: When popping try to keep text in forms
},
),
],
);
},
);
}
}
and here is the registerWithEmailAndPassword function:
Future registerWithEmailAndPassword(String email, String password,
String name, String description, int age) async {
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
user.sendEmailVerification();
user.isEmailVerified;
print('Email verification sent?');
//create a new document for the user with the uid
await DatabaseService(uid: user.uid)
.updateUserData(name: name, description: description, age: age);
await DatabaseService(uid: user.uid).updateUserPicture(
pictureURL:
'https://firebasestorage.googleapis.com/v0/b/independent-project-7edde.appspot.com/o/blank_profile_picture.png?alt=media&token=49efb712-d543-40ca-8e33-8c0fdb029ea5');
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
It was a mistake on my part with the Security rules. I had that users could create users but they could only read if they were authenticated, so when I checked if username was taken the error occurred since I did not have the read permissions. I just added the read part on users and it works
match /Users/{document=**} {
allow create: if true;
allow read: if true;
}
´´´