Flutter + Firebase updateDisplayName when creating account with Email and Password - firebase

I'm new to Flutter and really, really new to firebase.
I'm trying to create a user via the createUserWithEmailAndPasswordMethod.
I've successfully created on, but I'm trying to improve it by allowing the user to enter the desired username and setting said username to the displayName attribute.
My code is as follows:
_createUser() async {
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = _usernameController.text;
FirebaseUser user = await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
.then((user) {
user.updateProfile(updateInfo);
});
print('USERNAME IS: ${user.displayName}');
}
The problem is when I run the app it always throws this exception:
NoSuchMethodError: The getter 'displayName' was called on null.
Every time I debug the user variable keeps showing as null as well, even though the user is created and I can print the email and password!
I guess the problem is that Firebase user is null, but even if I move the print('USERNAME IS: ${user.displayName}'); to right after updateProfile the same happens.
Hope you guys can help!
Thanks.

You should not use await and then together. await is a substitute for then method.
_createUser() async {
await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
FirebaseUser user = await _auth.currentUser();
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = _usernameController.text;
user.updateProfile(updateInfo);
print('USERNAME IS: ${user.displayName}');
}

So, what worked for me was this: I had to call the reload() method to get the new user information after the updateProfile(). After some changes the method looks like this:
_createUser() async {
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = _usernameController.text;
await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
.then((user) async {
await user.updateProfile(updateInfo);
await user.reload();
FirebaseUser updatedUser = await _auth.currentUser();
print('USERNAME IS: ${updatedUser.displayName}');
Navigator.of(context).push(
MaterialPageRoute<Map>(
builder: (BuildContext context) {
return Posts(_googleSignIn, updatedUser);
},
),
);
}).catchError((error) {
print('Something Went Wrong: ${error.toString()}');
});
}

If someone is still searching, this is the working solution in 2021.
UserCredential userCred = await _auth.createUserWithEmailAndPassword(email, password);
await userCred.user.updateProfile(displayName: "Your Name");

Related

FirebaseUser not an existing class | authentication errors [duplicate]

I'm new to Flutter. I have an Issue with Firebase Auth/ Google Auth
The FirebaseUser is not defined
Code:
FirebaseAuth _auth = FirebaseAuth.instance;
GoogleSignIn googleSignIn = GoogleSignIn();
Future<FirebaseUser> currentUser() async { // The Issue is here in the Future<>
final GoogleSignInAccount account = await googleSignIn.signIn();
final GoogleSignInAuthentication authentication =
await account.authentication;
final GoogleAuthCredential credential = GoogleAuthProvider.getCredential(
idToken: authentication.idToken, accessToken: authentication.accessToken);
final AuthResult authResult = await _auth.signInWithCredential(credential);
final FirebaseUser user = authResult.user; // and here as I can't define this FirebaseUser object to return
return user;
}
Pubspec.yml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.3
firebase_auth: ^0.18.0
location: ^3.0.2
page_transition: ^1.1.6
google_sign_in: ^4.5.1
flutter_facebook_login: ^3.0.0
firebase_database: ^4.0.0
I also face the same issue with AuthResult
final AuthResult authResult = await _auth.signInWithCredential(credential);
Starting from Version firebase_auth 0.18.0:
In the newest version of firebase_auth, the class FirebaseUser was changed to User, and the class AuthResult was changed to UserCredential. Therefore change your code to the following:
Future<User> currentUser() async {
final GoogleSignInAccount account = await googleSignIn.signIn();
final GoogleSignInAuthentication authentication =
await account.authentication;
final GoogleAuthCredential credential = GoogleAuthProvider.credential(
idToken: authentication.idToken,
accessToken: authentication.accessToken);
final UserCredential authResult =
await _auth.signInWithCredential(credential);
final User user = authResult.user;
return user;
}
FirebaseUser changed to User
AuthResult changed to UserCredential
GoogleAuthProvider.getCredential() changed to GoogleAuthProvider.credential()
onAuthStateChanged which notifies about changes to the user's sign-in state was replaced with authStateChanges()
currentUser() which is a method to retrieve the currently logged in user, was replaced with the property currentUser and it no longer returns a Future<FirebaseUser>.
Example of the above two methods:
FirebaseAuth.instance.authStateChanges().listen((event) {
print(event.email);
});
And:
var user = FirebaseAuth.instance.currentUser;
print(user.uid);
Deprecation of UserUpdateInfo class for firebaseUser.updateProfile method.
Example:
Future updateName(String name, FirebaseUser user) async {
var userUpdateInfo = new UserUpdateInfo();
userUpdateInfo.displayName = name;
await user.updateProfile(userUpdateInfo);
await user.reload();
}
now
import 'package:firebase_auth/firebase_auth.dart' as firebaseAuth;
Future updateName(String name, auth.User firebaseUser) async {
firebaseUser.updateProfile(displayName: name);
await firebaseUser.reload();
}
Since firebase_auth 0.18.0, the class FirebaseUser was changed to User
In the newest version of firebase_auth, the class FirebaseUser was changed to User, and the class AuthResult was changed to UserCredentail. Therefore change FirebaseUser to User
The class FirebaseUser was changed to User
try this way
_registerUser() async {
try {
final User? user =
(await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailCtrl.text,
password: passCtrl.text,
))
.user;
FirebaseFirestore.instance.collection('users').doc().set({
'name': nameCtrl.text,
'uid': user!.uid,
'email': user.email,
'isEmailVerified': user.emailVerified, // will also be false
'photoUrl': user.photoURL, // will always be null
});
print("Created");
} catch (e) {
print(e.toString());
}
}
Run
flutter pub get
Then rebuild your app.
This can be your signin function with email and password as of Sept 2020.Initialze app is a new introduced method we must at least call once before we use any other firebase methods.
Future<void> signin() async {
final formState = _formkey.currentState;
await Firebase.initializeApp();
if (formState.validate()) {
setState(() {
loading = true;
});
formState.save();
try {
print(email);
final User user = (await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password))
.user;
} catch (e) {
print(e.message);
setState(() {
loading = false;
});
}
}
}

Undefined class 'FirebaseUser'

I'm new to Flutter. I have an Issue with Firebase Auth/ Google Auth
The FirebaseUser is not defined
Code:
FirebaseAuth _auth = FirebaseAuth.instance;
GoogleSignIn googleSignIn = GoogleSignIn();
Future<FirebaseUser> currentUser() async { // The Issue is here in the Future<>
final GoogleSignInAccount account = await googleSignIn.signIn();
final GoogleSignInAuthentication authentication =
await account.authentication;
final GoogleAuthCredential credential = GoogleAuthProvider.getCredential(
idToken: authentication.idToken, accessToken: authentication.accessToken);
final AuthResult authResult = await _auth.signInWithCredential(credential);
final FirebaseUser user = authResult.user; // and here as I can't define this FirebaseUser object to return
return user;
}
Pubspec.yml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.3
firebase_auth: ^0.18.0
location: ^3.0.2
page_transition: ^1.1.6
google_sign_in: ^4.5.1
flutter_facebook_login: ^3.0.0
firebase_database: ^4.0.0
I also face the same issue with AuthResult
final AuthResult authResult = await _auth.signInWithCredential(credential);
Starting from Version firebase_auth 0.18.0:
In the newest version of firebase_auth, the class FirebaseUser was changed to User, and the class AuthResult was changed to UserCredential. Therefore change your code to the following:
Future<User> currentUser() async {
final GoogleSignInAccount account = await googleSignIn.signIn();
final GoogleSignInAuthentication authentication =
await account.authentication;
final GoogleAuthCredential credential = GoogleAuthProvider.credential(
idToken: authentication.idToken,
accessToken: authentication.accessToken);
final UserCredential authResult =
await _auth.signInWithCredential(credential);
final User user = authResult.user;
return user;
}
FirebaseUser changed to User
AuthResult changed to UserCredential
GoogleAuthProvider.getCredential() changed to GoogleAuthProvider.credential()
onAuthStateChanged which notifies about changes to the user's sign-in state was replaced with authStateChanges()
currentUser() which is a method to retrieve the currently logged in user, was replaced with the property currentUser and it no longer returns a Future<FirebaseUser>.
Example of the above two methods:
FirebaseAuth.instance.authStateChanges().listen((event) {
print(event.email);
});
And:
var user = FirebaseAuth.instance.currentUser;
print(user.uid);
Deprecation of UserUpdateInfo class for firebaseUser.updateProfile method.
Example:
Future updateName(String name, FirebaseUser user) async {
var userUpdateInfo = new UserUpdateInfo();
userUpdateInfo.displayName = name;
await user.updateProfile(userUpdateInfo);
await user.reload();
}
now
import 'package:firebase_auth/firebase_auth.dart' as firebaseAuth;
Future updateName(String name, auth.User firebaseUser) async {
firebaseUser.updateProfile(displayName: name);
await firebaseUser.reload();
}
Since firebase_auth 0.18.0, the class FirebaseUser was changed to User
In the newest version of firebase_auth, the class FirebaseUser was changed to User, and the class AuthResult was changed to UserCredentail. Therefore change FirebaseUser to User
The class FirebaseUser was changed to User
try this way
_registerUser() async {
try {
final User? user =
(await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailCtrl.text,
password: passCtrl.text,
))
.user;
FirebaseFirestore.instance.collection('users').doc().set({
'name': nameCtrl.text,
'uid': user!.uid,
'email': user.email,
'isEmailVerified': user.emailVerified, // will also be false
'photoUrl': user.photoURL, // will always be null
});
print("Created");
} catch (e) {
print(e.toString());
}
}
Run
flutter pub get
Then rebuild your app.
This can be your signin function with email and password as of Sept 2020.Initialze app is a new introduced method we must at least call once before we use any other firebase methods.
Future<void> signin() async {
final formState = _formkey.currentState;
await Firebase.initializeApp();
if (formState.validate()) {
setState(() {
loading = true;
});
formState.save();
try {
print(email);
final User user = (await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password))
.user;
} catch (e) {
print(e.message);
setState(() {
loading = false;
});
}
}
}

Undefined class 'UserUpdateInfo' in Firebase_auth (Flutter 2020)

I am using Flutter with the 'Firebase_auth' package.
While I am making the following signUp function, I get an error on the 'UserUpdateInfo'.
signup(CustomUser user, AuthNotifier authNotifier) async {
UserCredential userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: user.email, password: user.password)
.catchError((error) => print(error.code));
if (userCredential != null) {
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = user.displayName;
User firebaseUser = userCredential.user;
if (firebaseUser != null) {
await firebaseUser.updateProfile(updateInfo);
await firebaseUser.reload();
print("Sign up: $firebaseUser");
User currentUser = await FirebaseAuth.instance.currentUser();
authNotifier.setUser(currentUser);
}}}
The following error is shown:
Undefined class 'UserUpdateInfo'
What can I do about it?
It seems like you've updated your Firebase_Auth package. UserUpdateInfo is now deprecated. Try this instead:
await FirebaseAuth.instance.currentUser.updateProfile(displayName:user.displayName);

Firebase can not change displayName ,displayName is null on every way

Can't add I more user information with await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: _email, password: _password); function?
part of signup.dart file:
String _email, _password, _name;
final formkey = new GlobalKey<FormState>();`
Future<void> registered() async {
if (formkey.currentState.validate()) {
formkey.currentState.save();
try {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: _email, password: _password);
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
Firestore.instance
.collection("users")
.document(firebaseUser.uid)
.setData({"name": _name});
await firebaseUser.reload();
firebaseUser = await FirebaseAuth.instance.currentUser();
print(
"${firebaseUser.uid},${firebaseUser.email},${firebaseUser.displayName} , $_password this user has been created-----");
} catch (e) {
print("${e.message} message--------------------------------------");
}
} else {
print("somthing went wrong");
}
}
I have tried many way to do this but still i have no result
You are saving data in Firestore, and trying to get the name from Firebase Auth. Those are two services. Instead of trying to use firestore, what you could is,
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
var userUpdateInfo = UserUpdateInfo();
userUpdateInfo.displayName = _name;
firebaseUser.updateProfile(userUpdateInfo);
await firebaseUser.reload();
firebaseUser = await FirebaseAuth.instance.currentUser();
After creating the account using the method .createUserWithEmailAndPassword pass the value of the user to another class by
final FirebaseAuth _auth = FirebaseAuth.instance;
//user object based on firebase
User _userFromFirebase(FirebaseUser user){
return user != null ? User(uid: user.uid):null;
}
Future loginWithEmailAndPass(String email,String password)async{
try{
AuthResult result = await _auth.signInWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
return _userFromFirebase(user);
}catch(e){
print(e.toString());
return null;
}
}
Pass the value of user to a new class by creating a new dart file
class User{
final String uid;
User({this.uid});
}
Include that dart file in the home page for the user name.
Refer this tutorial for guidance.
https://youtu.be/Jy82t4IKJSQ?list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC

How to make Flutter sign up with more fields?

My sign up page has the following fields Names, password, confirm password and email but it seems flutter firebase only works for email and password.
How do I make more fields work in the below code:
createUser()async{
if (checkFields()){
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: _email, password: _password)
.then((user){
print('signed in as ${user.uid}');
Navigator.push(context, MaterialPageRoute(builder: (context)=> (Usertype())));
}).catchError((e){
print(e);
});
}
}
Unfortunately, you cannot make Firebase accept Names on sign up event.
But you can update user information after sign up.
Use updateProfile method after authentication is successfully complete.
You can check this as Android example, and here as the method from the Flutter package.
In your case,
createUser()async{
if (checkFields()){
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: _email, password: _password)
.then((user){
print('signed in as ${user.uid}');
var userUpdateInfo = new UserUpdateInfo(); //create user update object
userUpdateInfo.displayName = name; //set user display name to your variable.
await firebaseAuth.updateProfile(userUpdateInfo); //update the info
await user.reload(); //reload the user data
Navigator.push(context, MaterialPageRoute(builder: (context)=> (Usertype())));
}).catchError((e){
print(e);
});
}
}

Resources