The email address is badly formatted - Flutter firebase - firebase

FirebaseAuthException ([firebase_auth/invalid-email] The email address is badly formatted
when I uses flutter firebase email password auth it shows email adress badly formated. name and vehicle number is also pass to the database when authentication process is there any problem in it. why it occurs. if someone can help me to find out the problem help me
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20.0))),
elevation: 5.0,
height: 40,
onPressed: () {
setState(() {
showProgress = true;
});
signUp(
emailController.text,
passwordController.text,
role,
vehicleNo.text,
name.text);
},
child: Text(
"Register",
style: TextStyle(
fontSize: 20,
),
),
color: Colors.white,
)
],
),
],
),
),
),
),
),
],
),
),
);
}
void signUp(String name, String email, String password, String role,
String vehicleNo) async {
const CircularProgressIndicator();
if (_formkey.currentState!.validate()) {
await _auth
.createUserWithEmailAndPassword(
email: email.trim(), password: password.trim())
.then(
(value) => {
postDetailsToFirestore(
email,
role,
name,
vehicleNo,
),
},
)
.catchError((e) {
print("its an error");
});
}
}
postDetailsToFirestore(
String email, String role, String name, String vehicleNo) async {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
User? user = _auth.currentUser;
UserModel userModel = UserModel();
userModel.email = email;
userModel.name = name;
userModel.vehicleNo = vehicleNo;
userModel.uid = user!.uid;
userModel.role = role;
await firebaseFirestore
.collection("users")
.doc(user.uid)
.set(userModel.toMap());
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => LoginScreen()));
}
}

When executing the SignUp function (at Material Button OnPressed), are the variables passed in the wrong order?

You're calling:
signUp(
emailController.text,
passwordController.text,
role,
vehicleNo.text,
name.text);
And signUp is defined as:
void signUp(String name, String email, String password, String role,
String vehicleNo) async {
So the order of the arguments is different between the two, leading you to call Firebase with the password value as the email address and the role value as the password.
To fix the problem, pass the arguments in the same order as signUp expects them.

It's almost always trailing whitespace, try:
postDetailsToFirestore(
email.trim(),
role,
name,
vehicleNo,
),
Alternatively you can also try to hardcode the right email address and check whether the problem is in logic or in UI.

Related

How to pass data between classes? Flutter

I have a class which I get email data from the user. It's basicly a textfield so I wont post the textfield code. After I get the email and password data, I check if these data is in my Firestore database. If it is, I want to pass this email data to my other class which I get the other informations about customer.
Here is the code of trying to check if user exists when I click the button.This is my LoginScreen() class' Material Button's onPressed action. I only get the email from the user here and want to pass this email data to my CustomerInfo class if the user already exists in my FirebaseAuth.Also the CustomerScreen class is for the show all customer information on the screen. I will add some code to push the customer information after I successfully get the data form database.
try {
final user = await _auth.signInWithEmailAndPassword(
email: email!, password: password!);
if (user != null) {
CustomerInfo(email: email);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerScreen()));
}
} catch (e) {
print(e);
}
Also I have another class which I'm trying to get customers data.
class CustomerInfo {
String? email;
String? name;
String? surname;
String? avatarLink;
int? balance;
CollectionReference customers =
FirebaseFirestore.instance.collection('customers');
CustomerInfo({this.email});
Future getCustomerData() async {
print("Email: $email");
await customers.where('email', isEqualTo: email).get().then((value) {
value.docs.forEach((result) {
name = result['name'];
surname = result['surname'];
balance = result['balance'];
avatarLink = result['image'];
});
});
}
}
Also CustomerInfo class:
import 'package:banking_app_firebase/constants.dart';
import 'package:banking_app_firebase/networking.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'login_screen.dart';
class CustomerScreen extends StatefulWidget {
const CustomerScreen({Key? key}) : super(key: key);
#override
_CustomerScreenState createState() => _CustomerScreenState();
}
class _CustomerScreenState extends State<CustomerScreen> {
String? name;
String? surname;
int? balance;
String? image;
void getData() async {
CustomerInfo customerInfo = CustomerInfo();
await customerInfo.getCustomerData();
name = customerInfo.name;
print("Name: $name");
}
#override
void initState() {
// TODO: implement initState
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(
color: Colors.black,
),
title: Text(
"Account Summary",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
actions: [
Container(
padding: EdgeInsets.only(right: 10),
child: Row(
children: [
Icon(
CupertinoIcons.bell,
color: Colors.black,
),
SizedBox(
width: 10,
),
CircleAvatar(
backgroundImage: NetworkImage(
"https://cdn.pixabay.com/photo/2016/03/23/04/01/woman-1274056_960_720.jpg"),
),
],
),
),
],
elevation: 0,
),
body: Container(
child: Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
"Deneme",
style: kInfoTextDecoration,
),
),
Align(
alignment: Alignment.topLeft,
child: Text(
"Deneme",
style: kInfoTextDecoration,
),
),
],
),
),
);
}
}
How can I pass the email data to my CustomerInfo class so I can use getCustomerData()? Using CustomerInfo(email:email) did not work.
I am sorry, I think I misunderstood your question.
Is this what you are trying to do? You are passing email correctly. You just need to call getCustomerData()
try {
final user = await _auth.signInWithEmailAndPassword(
email: email!, password: password!);
if (user != null) {
var customerInfo = CustomerInfo(email: email);
await customerInfo.getCustomerData();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerScreen(customerInfo: customerInfo)));
}
} catch (e) {
print(e);
}
Then in CustomerScreen it would look like this
class CustomerScreen extends StatefulWidget {
final CustomerInfo customerInfo;
const CustomerScreen({Key? key, this.customerInfo}) : super(key: key);
#override
_CustomerScreenState createState() => _CustomerScreenState();
}
class _CustomerScreenState extends State<CustomerScreen> {
String? name;
String? surname;
int? balance;
String? image;
void getData() {
name = widget.customerInfo.name;
surname = widget.customerInfo.surname;
balance = widget.customerInfo.balance;
image = widget.customerInfo.image;
}
But I would recommend you take a look into FutureBuilder.
this will not work as the email field is not static so you can't use CustomerInfo.getCustomerData(). You need to create an instance of custom user and then use the getCustomerData() method.
For example: var data = await CustomerInfo(email: email).getCustomerData();
or if you are going to use the CustomerInfo()` multiple times you can do the following:
final CustomerInfo info = CustomerInfo(email: email);
var data = info.getCustomerData();
or something similar to that.
If you are trying to display the info inside of the CustomScreen() I think it might be easier to just create a CustomerInfo() there and get whatever data you need.
All I can do is guess as you haven't provided a sample for CustomScreen() or what it is meant to do. If you are trying to the customer data in the CustomScreen() then it might be better to use a FutureBuilder() to show your user that the data is loading then display it once the future completes rather than just having an async callback before pushing the route making the user think that they didn't click the button.
It depends on your preferences. For example, usually, I create a global.dart and store temporary variables there. for example in your global.dart:
CustomerInfo selectedUser;
then you can set it wherever you want. for example:
import './global.dart' as global;
try {
final user = await _auth.signInWithEmailAndPassword(
email: email!, password: password!);
if (user != null) {
CustomerInfo(email: email);
global.selectedUser = CustomeInfo(SET PARAMETERS);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerScreen()));
}
} catch (e) {
print(e);
}
the you can use it by calling global.selectedUser wherever you want.
Other approach is using Provider but it is useful when you want to change the variable in many files.
Also, you can use firebase methods for getting active user and his/her info like getEmail() but I do not recommend it because of unnecessary API call.
Get the email info from _auth.
try {
final user = await _auth!.signInWithEmailAndPassword(
email: email!, password: password!);
if (user.user !=null) { // added user.user
CustomerInfo(email: user.user!.email); //added user.user!.email
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerScreen()));
}
} catch (e) {
print(e);
}

Create Multiple User Credentials without loosing current state (logged in user) Firebase Flutter

I want to be logged in as an admin but also wanna create user login credentials for other users. using createUserWithEmailAndPassword() method but it accidentally logging a newly created user.
enter image description hereI have tried the other methods but not working in my case. Please helps me with this.
SAMPLE CODE::
class _TestScreenState extends State<TestScreen> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final FirebaseFirestore _fs = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
bool _isLoading = false;
final User _currentUser = FirebaseAuth.instance.currentUser;
Future<void> _createUser() async {
try {
setState(() {
_isLoading = true;
});
await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
.then((UserCredential _user) async {
try {
await _fs.collection('users').doc(_user.user.uid).set({
'email': _emailController.text,
'password': _passwordController.text,
}).then((value) {
setState(() {
_isLoading = false;
});
});
} catch (err) {
_user.user.delete();
print("User Deleted");
setState(() {
_isLoading = false;
});
}
});
} catch (err) {
print("Cannot Sign Up: $err");
setState(() {
_isLoading = false;
});
}
}
#override
Widget build(BuildContext context) {
print("USER--" + _currentUser.uid);
return Scaffold(
appBar: AppBar(title: Text("Test Screen")),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
TextField(
controller: _emailController,
),
SizedBox(
height: 20,
),
TextField(
controller: _passwordController,
),
SizedBox(height: 30),
ElevatedButton(
onPressed: _createUser,
child: Text(_isLoading ? "Creating..." : "Create User"),
),
],
),
),
);
}
}
In Firebase Authentication there is a single signed-in user for each FirebaseAuth object. If you want to sign in multiple users, you will need multiple instances of the FirebaseAuth class, based on an explicit FirebaseApp object (instead of the default FirebaseAuth.instance).
Note that this is a common anti-pattern though. For example, wanting to have a administrative user in the app who can create other user accounts, is typically better handled by creating a custom back-end API (for example on Cloud Functions), where you can then the Admin SDK that is specifically made for such administrative functionality.

Flutter/Firebase/Firestore - Signup not pushing data to database

I am trying to record some additional user data when they sign up to my app. My signup process looks like this:
String ref = "users";
Future<bool> signUp(
String email,
String password,
String firstName,
String lastName,
) async {
try {
_status = Status.Authenticating;
notifyListeners();
await _auth
.createUserWithEmailAndPassword(email: email, password: password);
FirebaseFirestore.instance.collection(ref).doc(user.uid).set({
'id': user.uid,
'displayName': firstName.trim() + " " + lastName.trim(),
'email': email.trim(),
'createdat': DateTime.now()
});
return true;
} catch (e) {
_status = Status.Unauthenticated;
notifyListeners();
} return false;
}
I can't work out why, when the user enters their data and signs up, the specified values aren't pushed to firestore. Can someone help me out? Thanks. Here is where I have implemented my code:
child: RaisedButton(
child: Text('Create an Account', style: TextStyle(color: Colors.white),),
onPressed: () async {
if (validate()) {
_formKey.currentState.reset();
user.signUp(_emailController.text, _passwordController.text, _firstNameController.text, _lastNameController.text);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => Home()));
}
}),
So, as mentioned in the comments, it should be like this:
await FirebaseFirestore.instance.collection(ref).doc(user.uid).set({
'id': user.uid,
'displayName': firstName.trim() + " " + lastName.trim(),
'email': email.trim(),
'createdat': DateTime.now()
});

Get user UID after user registering

How to get user UID after user registration. I'm trying to do with getCurrentUser method but it ends up always null. Here is the method :
String userId;
#override
void initState() {
super.initState();
getCurrentUser();
}
getCurrentUser() async {
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
setState(() {
userId = firebaseUser.uid;
});
}
And here is the button when users wants to register and the data that user input will send to Firebase. But the userId always null.
Container(
height: 45.0,
width: 270.0,
child: RaisedButton(
child: Text('SIGN UP'),
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
final newUser =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
_firestore.collection('UserAccount').add({
'uid': userId,
'Email Address': email,
'Full Name': nama,
'Phone Number': phoneNumber,
});
if (newUser != null) {
Navigator.pushNamed(context, HomePage.id);
}
setState(() {
showSpinner = false;
});
} catch (e) {
print(e);
}
},
),
),
If I try to register with the code above, this error showed up.
Thank you for anyone who trying to help :(
You need to get the uid after registering:
final newUser =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
_firestore.collection('UserAccount').add({
'uid': newUser.user.uid,
'Email Address': email,
'Full Name': nama,
'Phone Number': phoneNumber,
});
newUser should return a value of type AuthResult and inside AuthResult it has a field of type FirebaseUser, therefore you can use newUser.user.uid.
If you want to get the data from the document based on the user id, then I recommend to do the following:
final newUser =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
_firestore.collection('UserAccount').document(newUser.user.uid).setData({
'Email Address': email,
'Full Name': nama,
'Phone Number': phoneNumber,
});

How to: Set Firebase user's profile info on signup/creation? (Flutter-web)

How can I set a user's displyName at the same time as creating their account?
I'm using the createUserWithEmailAndPassword method and trying to take the information from 3 different TextFormFields within the same Form.
Below is a very simple example of what I'm trying to do... Hopefully from this someone will be able to help..
Thanks
This is my signup method:
import 'package:firebase_auth/firebase_auth.dart';
class AuthService {
FirebaseAuth auth = FirebaseAuth.instance;
//Create user with email and password (+ displayName)
signUp({String email, String password, String name}) async {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
// I'd like to create/update the new user's displayName here, using the String value (name) being passed into this function.
}
}
This is an example of where the data is coming from:
class SignUpForm extends StatelessWidget {
final GlobalKey<FormState> _formKey = GlobalKey();
String name;
String email;
String password;
TextEditingController nameController;
TextEditingController emailController;
TextEditingController passwordController;
submit(){
AuthService().signUp(password: 'password', email: email, name: name);
}
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
controller: nameController,
onChanged: (value) {
name = value;
},
),
TextFormField(
controller: emailController,
onChanged: (value) {
email = value;
},
),
TextFormField(
controller: passwordController,
onChanged: (value) {
password = value;
},
),
],
),
);
}
}
The user object is returned from the createUserWithEmailAndPassword function's promise and you can then update the displayName immediately after by issuing a further request to firebase.
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password)
.then((user){
var userUpdateInfo = new UserUpdateInfo(); //create user update object
userUpdateInfo.displayName = "John Doe"
await firebaseAuth.updateProfile(userUpdateInfo); //update to firebase
await user.reload(); //reload user data
})
More info about UserUpdateInfo class here:
https://pub.dev/documentation/firebase_auth/latest/firebase_auth/UserUpdateInfo-class.html
You may also want to check out the example app on the firebase github repository. I've linked to the file and line which is relevant to what you are seeking to achieve:
https://github.com/FirebaseExtended/flutterfire/blob/7ccdd3b9bca948d15b397fe5c86ec4616b611c47/packages/firebase_auth/firebase_auth/example/lib/register_page.dart#L88
EDIT
Final working code:
class AuthService {
FirebaseAuth auth = FirebaseAuth.instance;
signUp({String email, String password, String name}) async {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password)
.then(
(value) async {
var userUpdateInfo = new UserUpdateInfo(); //create user update object
userUpdateInfo.displayName = "John Doe";
await value.user.updateProfile(userUpdateInfo); //update to firebase
await value.user.reload();
print('displayname= ${userUpdateInfo.displayName}');
},
);
}
}
_createUser() async {
await _auth
.createUserWithEmailAndPassword(
email: emailText,
password: passwordText,
)
FirebaseUser user = await _auth.currentUser();
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = 'John Doe';
await user.updateProfile(updateInfo);
print('USERNAME IS: ${user.displayName}');
}

Resources